[隨筆]GNU linker script,ld script,GNU鏈接腳本
注,此文部分內容摘抄自網絡,博主(itxiebo)主要的貢獻是整理編輯等。
________________________________________
一、什麼是GNU linker script?作用是什麼?
.lds文件,即linker script,決定了可執行映像(image)的鏈接方式,以及各個段的裝載地址(裝載域)和執行地址(運行域)。
- 裝載地址:運行之前各段的地址;
- 運行地址:運行時各段的地址。
________________________________________
二、對GNU linker script的簡單認識
首先,完整版的官網Gnulinkerscript下載地址如下,此文件可作爲參考文獻使用。
http://pan.baidu.com/s/1hriLMb6
GNU官方網站上對.lds文件形式的基本描述:
SECTIONS
{
...
secname start BLOCK(align)(NOLOAD) : AT(ldadr)
{ contents } >region :phdr =fill
...
}
• 1
• 2
• 3
• 4
• 5
• 6
• 7
兩個必須的(secname, contents),其他optional
- secname:段名,用以命名此段。
- contents:決定哪些內容放在本段,可以是整個目標文件(.o),也可以是目標文件中的某段(代碼段、數據段等)。
- start:是段的重定位地址,即本段運行的地址。如果代碼中有位置無關指令,程序運行時這個段必須放在這個地址上。start可以用任意一種描述地址的符號來描述。
- BLOCK(align) 指定塊對齊。比如,前一個段從0x30000000到0x300003F1,此處標記ALIGN(4),表示此處最小佔用4Bytes,即使下一個段是緊挨這個段,那麼下一個段的起始地址(也就是運行地址)爲0x300003F4。
- NOLOAD:告訴加載器程序運行時不加載該段到內存。
- AT(ldadr):定義本段存儲(加載)的地址,如果不使用這個選項,則加載地址等於運行地址,通過這個選項可以控制各段分別保存於輸出文件中不同的位置。
________________________________________
三、.lds相關的簡單實例
例:
/* nand.lds */
SECTIONS
{
first 0x00000000 : { head.o init.o }
second 0x30000000 : AT(4096) { main.o }
}
• 1
• 2
• 3
• 4
• 5
以上,
head.o放在0x00000000地址開始處,init.o放在head.o後面,他們的運行地址也是0x00000000,即存儲和運行地址相同(沒有AT指定);
main.o放在4096(0x1000,是AT指定的,存儲地址)開始處,但它的運行地址在0x30000000,運行之前需要從0x1000(加載地址處)複製到0x30000000(運行地址處),此過程也就需要讀取flash,把程序拷貝到相應位置才能運行。這就是存儲地址和運行地址的不同,稱爲加載時域和運行時域,可以在.lds連接腳本文件中分別指定。
________________________________________
另外,編寫好的.lds文件,在用arm-linux-ld鏈接命令時:
- 帶-Tfilename來調用執行,如arm-linux-ld -Tnand.lds x.o y.o -o xy.o
- 也用-Ttext參數直接指定鏈接地址,如arm-linux-ld -Ttext 0x30000000 x.o y.o -o xy.o
________________________________________
四、常用section的定義
- text section:存放程序代碼
- data section:存放數據
- bss section:存放未初始化的數據,在鏡像文件中,是不爲 bss 段分配空間的,所以如果你開一個很大的全局的未初始化的數組,鏡像文件的大小不會相應的變大。而只是在加載器將鏡像加載進內存時,纔會爲 bss 段分配空間
鏈接器:把各個目標文件的各種段進行重新組合。
________________________________________
最後,兩個命令,先保存起來,後面有機會再實踐一下。
- arm-linux-objdump -h vmlinux > vmlinux.txt
–輸出linux內核段信息到vmlinux.txt文本中。
- arm-linux-objdump -f vmlinux > sec_symbol.txt
–輸出內核段信息和符號到sec_symbol.txt文本中。
________________________________________
本文回溯
- 什麼是GNU linker script?作用是什麼?
- 對GNU linker script的簡單認識,核心SECTIONS的結構分析。
- 對鏈接器基本原理的理解。