日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

uboot.lds链接脚本分析

發布時間:2023/12/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 uboot.lds链接脚本分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?LDFLAGS += -Bstatic -T /board/smdk2410/u-boot.lds -Ttext 0x33F80000中-Ttext 0x33F80000是指定代碼段text的首地址是0x33F80000

1、鏈接腳本格式

<SECTIONS>基本命令

SECTIONS?描述輸出文件的映射圖:?->?輸出文件各段、各文件怎么放置

一個SECTIONS命令內部包含一個或多個段,段是連接腳本的基本單元,它?表示輸入文件某部分怎么放置;

格式:

SECTIONS{

? ...

secname start ALIGN(align)(NOLOAD):AT(ldadr)

{contents}>region:phdr=fill

...

}

secname:命名這個段??

contents:用來確定代碼的什么部分放在這個段

start:是這個段的重定位地址,也叫運行地址。如果代碼中有位置無關的?指令,程序在運行時必須放在這個地址上。

ALIGN(align):雖然指定了運行地址,但仍可以使用ALIGN(align)來指定?對齊的要求---這個對齊的地址才是真正的地址

(NOLOAD):來告訴加載器,在運行時不用加載這個段

AT(ldadr):指定這個段在編譯出來的映像文件中的地址——加載地址

2、程序分析

OUTPUT_FORMAT("elf32-littlearm",?"elf32-littlearm",?"elf32-littlearm")

/*指定輸出可執行文件是elf格式,32位ARM指令,小端*/
OUTPUT_ARCH(arm)

/*指定輸出可執行文件的平臺為ARM*/
ENTRY(_start)

/*指定輸出可執行文件的起始代碼段為_start*/
SECTIONS
{

/*指定可執行image文件的全局入口點,通常這個地址都放在ROM(flash)0x0位置。必須使編譯器知道這個地址,通常都是修改此處來完成*/
?.?=?0x00000000;/*;從0x0位置開始*/
?.?=?ALIGN(4);/*代碼以4字節對齊*/
?.text?:
?{
??cpu/arm920t/start.o?(.text)?

?? ?/*代碼的第一個代碼部分*/??
??*(.text)

??/*下面依次為各個text段函數*/
?}
?.?=?ALIGN(4);

/*代碼以4字節對齊*/
?.rodata?:?{?*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))?}

?/*指定只讀數據段*/
?.?=?ALIGN(4);

/*代碼以4字節對齊*/
?.data?:?{?*(.data)?}
?.?=?ALIGN(4);

/*代碼以4字節對齊*/
?.got?:?{?*(.got)?}

/*指定got段, got段是uboot自定義的一個段,?非標準段*/
?.?=?.;
?__u_boot_cmd_start?=?.;

/*把__u_boot_cmd_start賦值為當前位置,?即起始位置*/
?.u_boot_cmd?:?{?*(.u_boot_cmd)?}

?/*指定u_boot_cmd段, uboot把所有的uboot命令放在該段.*/
?__u_boot_cmd_end?=?.;

?/*把__u_boot_cmd_end賦值為當前位置,即結束位置*/
?.?=?ALIGN(4);

/*代碼以4字節對齊*/
?__bss_start?=?.;

?/*把__bss_start賦值為當前位置,即bss段的開始位置*/
?.bss?(NOLOAD)?:?{?*(.bss)?.?=?ALIGN(4);?}

/*指定bss段,告訴加載器不要加載這個段*/
?__bss_end?=?.;

/*把_end賦值為當前位置,即bss段的結束位置*/
}

3、查看反匯編文件

看完上面的解析思路本來應該是很清晰的,于是乎編譯u-boot,查看一下System.map,

30100000 T _start

30100020 t _undefined_instruction

30100024 t _software_interrupt

30100028 t _prefetch_abort

3010002c?t _data_abort

30100030 t _not_used

30100034 t _irq

30100038 t _fiq

發現?_start?的鏈接地址不是u-boot.lds中.text?的當前地址0x00000000,而是0x30100000,這就產生很多疑問了:

(1)?????為什么u-boot.lds指定的?.text?的首地址不起作用?

(2)?????0x30100000是什么地址,由誰指定.text的首地址是0x30100000的呢?

(3)?????假如有其他動作改變了?.text?的首地址,那么該動作跟u-boot.lds的優先級又是怎么決定的呢?

其實這三個問題都在Makefile的LDFLAGS?變量和u-boot.lds?中找到答案。

4、修改u-boot.lds

我們不妨試著修改一下u-boot.lds,把u-boot.lds修改成如下(紅色字體部分為修改過部分):

OUTPUT_FORMAT("elf32-littlearm",?"elf32-littlearm",?"elf32-littlearm")

/*指定輸出可執行文件是elf格式,32位ARM指令,小端*/
OUTPUT_ARCH(arm)

/*指定輸出可執行文件的平臺為ARM*/
ENTRY(_start)

/*指定輸出可執行文件的起始代碼段為_start*/
SECTIONS
{

/*指定可執行image文件的全局入口點,通常這個地址都放在ROM(flash)0x0位置。必須使編譯器知道這個地址,通常都是修改此處來完成*/
?.?=?0x30000000;/*;從0x0位置開始*/
?.?=?ALIGN(4);/*代碼以4字節對齊*/

.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
?.?=?ALIGN(4);

/*代碼以4字節對齊*/

?.text :
?{
??cpu/arm920t/start.o (.text)?

?? ?/*代碼的第一個代碼部分*/??
??*(.text)

??/*下面依次為各個text段函數*/
?}?

?/*指定只讀數據段*/
?.?=?ALIGN(4);

/*代碼以4字節對齊*/
?.data?:?{?*(.data)?}
?.?=?ALIGN(4);

/*代碼以4字節對齊*/
?.got?:?{?*(.got)?}

/*指定got段, got段是uboot自定義的一個段,?非標準段*/
?.?=?.;
?__u_boot_cmd_start?=?.;

/*把__u_boot_cmd_start賦值為當前位置,?即起始位置*/
?.u_boot_cmd?:?{?*(.u_boot_cmd)?}

?/*指定u_boot_cmd段, uboot把所有的uboot命令放在該段.*/
?__u_boot_cmd_end?=?.;

?/*把__u_boot_cmd_end賦值為當前位置,即結束位置*/
?.?=?ALIGN(4);

/*代碼以4字節對齊*/
?__bss_start?=?.;

?/*把__bss_start賦值為當前位置,即bss段的開始位置*/
?.bss?(NOLOAD)?:?{?*(.bss)?.?=?ALIGN(4);?}

/*指定bss段,告訴加載器不要加載這個段*/
?__bss_end?=?.;

/*把_end賦值為當前位置,即bss段的結束位置*/
}

上面對u-boot.lds主要做了兩點修改

(1)?????把0x00000000?改成?0x30000000。

(2)?????把?.text?和?.rodata?存放的地址調換了位置。

5、反匯編文件重查

重新編譯?u-boot,?查看System.map

30000000 R version_string

30000028 r C.27.2365

.

.

.

30100000 T _start

30100020 t _undefined_instruction

.

.

.6、 歸納

從上面的System.map部分內容可以看出:

(1)?????u-boot.lds設定的地址(0x00000000或0x30000000)是有效的。

(2)?????.text的地址仍然是30100000

跟著我們查看Makefile中的LDFLAGS變量,發現一條指令

LDFLAGS += -Ttext $(TEXT_BASE)??其中TEXT_BASE?是在u-boot根目錄的board文件夾的對應的開發板名字的子目錄下的config.mk文件中定義的

TEXT_BASE = 0x30100000

看到這里我們應該明白為什么_start,也就是.text的首地址總是等于0x30100000了,在連接的時候ld命令會把參數-Ttext指定的地址賦給.text,所以.text在u-boot.lds中的默認地址(當前地址)不起作用了。

總結

以上是生活随笔為你收集整理的uboot.lds链接脚本分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。