U-Boot的lds文件详解
?
U-Boot的lds文件详解 对于.lds文件,决定一个可执行程序的各个段的存储位置,以及入口地址,这也是链接定位的作用。这里以u-boot的lds为例说明uboot的链接过程。 首先看一下GNU官方网站上对.lds文件形式的完整描述: SECTIONS { /* nand.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 { ??????? . = 0x00000000???????????? ; 定位当前地址为0地址 ??????? . = ALIGN(4)???????????????? ; 代码以4字节对齐 ??????? .text :?????????????????????????????????????? ;指定代码段 ??????? { ?????????? cpu/arm920t/start.o (.text)? ; 代码的第一个代码部分 ????????? *(.text)??????????????????????? ;其它代码部分 ??????? } ??????? . = ALIGN(4) ??????? .rodata : { *(.rodata) }???????? ;指定只读数据段 ??????? . = ALIGN(4); ??????? .data : { *(.data) }???????????? ;指定读/写数据段 ??????? . = ALIGN(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); ???????? __bss_start = .?????????????????????????????????????? ; 把__bss_start赋值为当前位置,即bss段的开始位置 ??????? .bss : { *(.bss) }??????????????????????? ; 指定bss段 ???????? _end = .????????????????????????????????? ; 把_end赋值为当前位置,即bss段的结束位置 } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |