- 了解u-boot.lds
1.itop4412 u-boo.lds 如下所示:
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") #指定输出可执行文件是elf格式,32位ARM指令,小端
OUTPUT_ARCH(arm) #指定输出可执行文件的平台为ARM
ENTRY(_start) #指定输出可执行文件的起始代码段为_start.
SECTIONS
{
. = 0x00000000; /*指定可执行image文件的全局入口点,通常这个地址都放在ROM(flash)0x0位置。必须使编译器知道这个地址,通常都是修改此处来完成*/
. = ALIGN(4); #代码以4字节对齐
.text : #指定代码段:必须将start.o文件放在代码段的开始位置,其它文件可任意放
{
cpu/arm_cortexa9/start.o (.text) #代码段第一部分,指明start.s是入口程序,被放到代码段开头
cpu/arm_cortexa9/s5pc210/cpu_init.o (.text)
board/samsung/smdkc210/lowlevel_init.o (.text)
common/ace_sha1.o (.text)
*(.text) #其它代码部分.其中的*表示其它任意文件,即所有其它文件的代码段
}
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } #指定只读数据段,RO段
. = ALIGN(4);
.data : { *(.data) } #指定读/写数据段,RW段
. = 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段的结束位置
}
分析得知:
- 在链接脚本中规定start.o(对应于start.S)作为整个u-boot的起始点,所以启动u-boot时会执行首先执行start.S。
- 一般来说,内存空间可分为代码段、数据段、全局变量段、未初始化变量区、栈区、堆区等。其中,栈区由指针SP决定,堆区实质上是由C代码实现的,其它段则由编译器决定。从上面分析看出,从0x00000000地址开始,编译器首先将代码段放在最开始的位置,然后是数据段,然后是bss段(未初始化变量区)。
执行编译u-boot,查看u-boot.map:
175 .text 0xc3e00000 0x27a48
176 cpu/arm_cortexa9/start.o(.text)
177 .text 0xc3e00000 0x760 cpu/arm_cortexa9/start.o
178 0xc3e00010 _start
179 0xc3e00050 _end_vect
180 0xc3e00058 _armboot_start
181 0xc3e0005c _bss_start
182 0xc3e00060 _bss_end
如上所示,发现 _start 的链接地址不是u-boot.lds中.text 的当前地址0x00000000,而是0xc3e00000,why?
-
为什么u-boot.lds指定的 .text 的首地址不起作用?
-
0xc3e00000由谁指定为.text的首地址?
在Makefile的LDFLAGS 变量和u-boot.lds 中可以寻找到答案:
config.mk:
LDFLAGS += -Bstatic -T $(obj)u-boot.lds $(PLATFORM_LDFLAGS)
ifneq ($(TEXT_BASE),)
LDFLAGS += -Ttext $(TEXT_BASE)
endif
如上所示,TEXT_BASE 定义在:
board/samsung/smdkc210/config.mk:
TEXT_BASE = 0xc3e00000
验证一下,修改该值为:TEXT_BASE = 0xc3f00000,重新编译一下u-boot,查看u-boot.map:
170 Linker script and memory map
171
172 0x00000000 . = 0x0
173 0x00000000 . = ALIGN (0x4)
174
175 .text 0xc3f00000 0x27a48
176 cpu/arm_cortexa9/start.o(.text)
177 .text 0xc3f00000 0x760 cpu/arm_cortexa9/start.o
178 0xc3f00010 _start
179 0xc3f00050 _end_vect
180 0xc3f00058 _armboot_start
181 0xc3f0005c _bss_start
182 0xc3f00060 _bss_end
183 0xc3f00294 copy_from_nand
184 0xc3f002e0 theLastJump
看到这里应该明白_start,也就是.text的首地址如何指定,在链接的时候ld命令会把参数-Ttext指定的地址赋给.text,所以.text在u-boot.lds中的默认地址(当前地址)不起作用了。