本文转自:http://blog.163.com/li_nian_you/blog/static/448537212013620910852/
.lds文件定义了整个程序编译之后的连接过程,决定了一个可执行程序的各个段的存储位置。GNU官方网站上对.lds文件形式的完整描述:
SECTIONS{... secname start BLOCK(align) (NOLOAD):AT (ldadr) {contents} >region:phdr=fill...}
SECTIONS { Firtst 0x00000000: {head.o init.o} Second 0x30000000: AT(4096){main.o} }
relocate: /*把U-Boot重新定位到RAM*/ adr r0,_start /*r0是代码的当前位置*/ /*adr伪指令,汇编器自动通过当前PC的值算出如果执行到_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("elf32littlearm","elf32littlearm","elf32littlearm"); //指定输出可执行文件是elf格式,32位ARM指令,小端 OUTPUT_ARCH(arm); //指定输出可执行文件的平台为ARM ENTRY(_start) ; //指定输出可执行文件的起始代码段为_start. SECTIONS { .=0x00000000; //从0x0位置开始 .=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段的结束位置 }