一、脚本分析
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") /* 指定输出可执行文件是elf格式,32位ARM指令,小端*/
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm) /* 指定输出文件的平台体系是 ARM */
ENTRY(_start) /* 指定可执行映像文件的起始段的段名是_start */
SECTIONS
{
. = 0x00000000; /* 指定可执行image文件的全局入口的入口地址 */
. = 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_start为起始地址 进行查找就可以很快查找到某一个命令
的定义的地址,并依据命令定义中函数指针调用相应的函数来执行命令。这段空间的长度并没有严格限制,用户可以添加一些u-boot
的命令,最终都会在连接是存放在这个位置*/
__u_boot_cmd_end = .; /* u_boot_cmd段结束位置,由此可以看出,*/
. = ALIGN(4);
__bss_start = .; /*把__bss_start赋值为当前位置,即bss段的开始位置*/
.bss : { *(.bss) } /*指定bss段 */
_end = .; /*把_end赋值为当前位置,即bss段的结束位置*/
}
二、uboot连接脚本上显示的全局起始连接地址是0x0,但是实际编译的地址是0x33f80000,为什么?
连接命令:-T /work/u-boot-1.1.6/board/smdk2410/u-boot.lds -Ttext 0x33f80000
解释:正是由于加入红色部分选项,会将全局起始连接地址更改成以text定义的0x33f80000。
三、疑问:使用-Ttext 0x33f80000并不会在下述情形中有效
将lds脚本更改成如下模样
. = 0x00000000; . = ALIGN(4); text : //注意text前边没有".",而u-boot.lds中是有的 { cpu/arm920t/start.o (.text) *(.text) }
再来执行编译命令-T /work/u-boot-1.1.6/board/smdk2410/u-boot.lds -Ttext 0x33f80000,就不能成功的更改连接地址,i don't know why。