u-boot.lds檔案詮釋
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
/*程式碼的第一個程式碼部分*/*(.text)
/*下面依次為各個text段函式*/}.= ALIGN(4);
/*程式碼以4位元組對齊*/.rodata :{*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))}
/*指定只讀資料段*/.= ALIGN(4);
/*程式碼以4位元組對齊*/.data :{*(.data)}.= ALIGN(4);
/*程式碼以4位元組對齊
/*指定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_end =.;
/*把_end賦值為當前位置,即bss段的結束位置*/}
看完上面的解析思路本來應該是很清晰的,於是乎編譯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 中找到答案。我們不妨試著修改一下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 存放的地址調換了位置。
重新編譯 u-boot,