1. 程式人生 > >u-boot.lds檔案詮釋

u-boot.lds檔案詮釋

u-boot.lds檔案詮釋

網上大部分u-boot.lds檔案的分析大部分都是千遍一律,例如下面就是本人在網上找到的關於u-boot.lds的資料。

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

/*指定輸出可執行檔案是elf格式,32ARM指令,小端*/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段的結束位置*/}

看完上面的解析思路本來應該是很清晰的,於是乎編譯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的優先順序又是怎麼決定的呢?

其實這三個問題都在MakefileLDFLAGS 變數和u-boot.lds 中找到答案。我們不妨試著修改一下u-boot.lds,把u-boot.lds修改成如下(紅色字型部分為修改過部分)

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

/*指定輸出可執行檔案是elf格式,32ARM指令,小端*/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,