連結指令碼再探和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(載入地址)是程式在執行前的載入過程使用的地址也可以理解為儲存地址即一個程式應該將程式儲存在哪裡的描述,這個地址一般由作業系統或引導程式碼使用。而大多數情況下載入地址是和虛擬地址相同的。因為一個可執行檔案作為一個整體被放在記憶體中開始執行大多數情況下是不需要對可執行檔案重新進行移動了。
以上都是我自己現在對連結指令碼中的地址的含義的理解如果有不對的麻煩指出,共同進步。