鏈接腳本再探和VMA與LMA
鏈接腳本簡單描述
連接腳本的描述都是以節(section)的單位的,網上也有很多描述鏈接腳本語法的好文章,再不濟還有官方的說明文檔可以用來學習,其實主要就是對編譯構建的整個過程有了深入的理解后就能對鏈接腳本的理解更加容易了,我這里只是簡單的記錄一下鏈接腳本最基礎核心的內容。鏈接腳本描述一個輸出節的方式如下:
SECTION> [ADDRESS] [(TYPE)] : [AT(LMA)]
{
OUTPUT-SECTION-COMMAND
OUTPUT-SECTION-COMMAND
...
} [>REGION] [AT>LMA_REGION] [:PHDR :PHDR...] [=FILLEXP]
其中:
SECTION 為輸出段的名字定義
[ADDRESS] 為輸出段的VMA 虛擬地址
[(TYPE)] 為輸出段的類型
[AT(LMA)] 為輸出段的LMA 加載地址
[>REGION] 為輸出段的VMA 地址依次累加
[AT>LMA_REGION] 為輸出段的LMA 地址依次累加
[:PHDR :PHDR...],[=FILLEXP] 很少用
OUTPUT-SECTION-COMMAND 為輸入段的模式匹配,定義那輸入些段會被放到這個輸出段中,需要注意的是
[ADDRESS] 和 [AT(LMA)]必須指定具體的地址。[><region>] 和 [AT>LMA region]只需指定MEMORY定義的內存空間,具體地址緊接著上一個output section的末尾地址。
REGION 區域的定義
主要是用來描述ROM和RAM的地址分布(Memory Map)。定義的方式如下:
MEMORY { name [attr] : ORIGIN = origin, LENGTH = len ... }
其中
<name> 是所要定義的內存區域的名字,
<origin> 是其起始地址,
<len> 為內存區域的大小。
<attr> 屬性描述如rx,rw等是可選的
虛擬地址(VMA)和加載地址(LMA)
VMA(虛擬地址)是指程序本身運行過程的地址空間,是指令中使用的地址。比如一條絕對跳轉指令使用的地址就是虛擬地址。所以虛擬地址有時候也會被稱為運行地址(鏈接地址)。之所以稱之為虛擬地址因為在有MMU的平臺上程序運行使用的都是虛擬地址所以虛擬地址==運行地址(鏈接地址)。LMA(加載地址)是程序在執行前的加載過程使用的地址也可以理解為存儲地址即一個程序應該將程序存儲在哪里的描述,這個地址一般由操作系統或引導代碼使用。而大多數情況下加載地址是和虛擬地址相同的。因為一個可執行文件作為一個整體被放在內存中開始運行大多數情況下是不需要對可執行文件重新進行移動了。
以上都是我自己現在對鏈接腳本中的地址的含義的理解如果有不對的麻煩指出,共同進步。

浙公網安備 33010602011771號