u boot lds檔案詳解

2021-05-27 16:44:30 字數 3010 閱讀 1568

對於.lds檔案,決定乙個可執行程式的各個段的儲存位置,以及入口位址,這也是鏈結定位的作用。這裡以u-boot的lds為例說明uboot的鏈結過程。

首先看一下gnu官方**上對.lds檔案形式的完整描述:

sections >region :phdr =fill

...}

secname和contents是必須的,前者用來命名這個段,後者用來確定**中的什麼部分放在這個段,以下是對這個描述中的一些關鍵字的解釋。

1、secname:段名

2、contents:決定哪些內容放在本段,可以是整個目標檔案,也可以是目標檔案中的某段(**段、資料段等)

3、start:是段的重定位位址,本段連線(執行)的位址,如果**中有位置無關指令,程式執行時這個段必須放在這個位址上。start可以用任意一種描述位址的符號來描述。

4、at(ldadr):定義本段儲存(載入)的位址,如果不使用這個選項,則載入位址等於執行位址,通過這個選項可以控制各段分別儲存於輸出檔案中不同的位置。

例:/* nand.lds */

sections

second 0x30000000 : at(4096)

}以上,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。

既然程式有了兩種位址,就涉及到一些跳轉指令的區別。

arm彙編中,常有兩種跳轉方法:b跳轉指令、ldr指令向pc賦值。

要特別注意這兩條指令的意思:

(1)       b step:b跳轉指令是相對跳轉,依賴當前pc的值,偏移量是通過該指令本身的    bit[23:0]算出來的,這使得使用b指令的程式不依賴於要跳到的**的位置,只看指令本身。

(2)       ldr pc, =step :該指令是乙個偽指令編譯後會生成以下**:

ldr pc, 0x30008000

<0x30008000>

step

是從記憶體中的某個位置(step)讀出資料並賦給pc,同樣依賴當前pc的值,但是偏移量是step的連線位址(執行時的位址),所以可以用它實現從flash到ram的程式跳轉。

(3) 此外,有必要回味一下adr偽指令,u-boot中那段relocate**就是通過adr實現當前程式是在ram中還是flash中:

relocate:                                   /* 把u-boot重新定位到ram */

adr r0, _start                       /* r0是**的當前位置 */

/* adr偽指令,彙編器自動通過當前pc的值算出這條指令中「_start"的值,執行到_start時pc的值放到r0中:

當此段在flash中執行時r0 = _start = 0;當此段在ram中執行時_start = _text_base(在board/smdk2410/config.mk中指定的值為0x33f80000,即u-boot在把**拷貝到ram中去執行的**段的開始) */

ldr r1, _text_base                       /* 測試判斷是從flash啟動,還是ram */

/* 此句執行的結果r1始終是0x33ff80000,因為此值是鏈結指定的 */

cmp r0, r1                                    /* 比較r0和r1,除錯的時候不要執行重定位 */

結合u-boot.lds談談連線指令碼。

output_format("elf32­littlearm", "elf32­littlearm", "elf32­littlearm")

;指定輸出可執行檔案是elf格式,32位arm指令,小端

output_arch(arm)

;指定輸出可執行檔案的平台為arm

entry(_start)

;指定輸出可執行檔案的起始**段為_start.

sections

. = align(4)

.rodata :         ;指定唯讀資料段

. = align(4);

.data :             ;指定讀/寫資料段

. = align(4);

.got :                         ;指定got段, got段式是uboot自定義的乙個段, 非標準段

__u_boot_cmd_start = .          ;把__u_boot_cmd_start賦值為當前位置, 即起始位置

.u_boot_cmd :           ;指定u_boot_cmd段, uboot把所有的uboot命令放在該段.

__u_boot_cmd_end = .                          ;把__u_boot_cmd_end賦值為當前位置,即結束位置

. = align(4);

__bss_start = .                                       ; 把__bss_start賦值為當前位置,即bss段的開始位置

.bss :                         ; 指定bss段

_end = .                                  ; 把_end賦值為當前位置,即bss段的結束位置

}

u boot lds檔案詳解

源文來自http blog.csdn.net dongliqiang2006 archive 2009 12 01 4915836.aspx 對於.lds檔案,決定乙個可執行程式的各個段的儲存位置,以及入口位址,這也是鏈結定位的作用。這裡以u boot的lds為例說明uboot的鏈結過程。首先看一下...

u boot lds檔案詳解

對於.lds檔案,決定乙個可執行程式的各個段的儲存位置,以及入口位址,這也是鏈結定位的作用。這裡以u boot的lds為例說明uboot的鏈結過程。首先看一下gnu官方 上對.lds檔案形式的完整描述 sections region phdr fill secname和contents是必須的,前者...

mysql檔案詳解 MySQL日誌檔案詳解

概述 日誌檔案是mysql資料庫的重要組成部分。mysql有幾種不同的日誌檔案,通常包括錯誤日誌檔案,二進位制日誌,通用日誌,慢查詢日誌,等等。這些日誌可以幫助我們定位mysqld內部發生的事件,資料庫效能故障,記錄資料的變更歷史,使用者恢復資料庫等等。本文主要描述mysql的各種日誌檔案。1.錯誤...