uboot版本2016.03
uboot.lds文件
在uboot在编译完成后会在原始链接脚本的基础下在根目录下生成uboot.lds文件。链接脚本代码如下:
/*指定输出可执行文件是elf格式,32位ARM指令,小端*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*指定运行平台为arm*/
OUTPUT_ARCH(arm)
/*指定uboot起始代码段*/
ENTRY(_start)
SECTIONS
{
/*指定可执行文件的全局入口点,通常这个地址都是0x0位置*/
. = 0x00000000;
/*代码4字节对齐*/
. = ALIGN(4);
/*代码段*/
.text :
{
/*uboot将自己拷贝的起始地址*/
*(.__image_copy_start)
/*中断向量表*/
*(.vectors)
/*中断向量表后接着是start.s文件*/
arch/arm/cpu/armv7/start.o (.text*)
/*其他的代码存放*/
*(.text*)
}
/*4字节对齐*/
. = ALIGN(4);
/*代码段之后放只读数据段*/
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
/*4字节对齐*/
. = ALIGN(4);
/*可读写数据段*/
.data : {
*(.data*)
}
. = ALIGN(4);
. = .;
. = ALIGN(4);
/*uboot自由的一些function,比如uboot command等*/
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
}
. = ALIGN(4);
/*至此,u-boot需要自拷贝的内容结束,包括代码段,数据段,以及u_boot_list*/
.image_copy_end :
{
*(.__image_copy_end)
}
.rel_dyn_start :
{
*(.__rel_dyn_start)
}
.rel.dyn : {
*(.rel*)
}
.rel_dyn_end :
{
*(.__rel_dyn_end)
}
.end :
{
*(.__end)
}
_image_binary_end = .;
. = ALIGN(4096);
.mmutable : {
*(.mmutable)
}
/*bss段映射地址*/
.bss_start __rel_dyn_start (OVERLAY) : {
KEEP(*(.__bss_start));
__bss_base = .;
}
.bss __bss_base (OVERLAY) : {
*(.bss*)
. = ALIGN(4);
__bss_limit = .;
}
/*bss段描述结束*/
.bss_end __bss_limit (OVERLAY) : {
KEEP(*(.__bss_end));
}
.dynsym _image_binary_end : { *(.dynsym) }
.dynbss : { *(.dynbss) }
.dynstr : { *(.dynstr*) }
.dynamic : { *(.dynamic*) }
.plt : { *(.plt*) }
.interp : { *(.interp*) }
.gnu.hash : { *(.gnu.hash) }
.gnu : { *(.gnu*) }
.ARM.exidx : { *(.ARM.exidx*) }
.gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
}
由uboot.lds文件的代码ENTRY(_start),得知uboot启动后会从符号_start所在位置开始运行。
总而言之,u-boot.lds脚本文件告诉链接器linker如何布局代码段、数据段、bss段等,已经配置了u-boot自拷贝(从flash到RAM的copy)的内容。另外,还简要的涉及了动态链接技术等。
u-boot 在编译之后会在其顶级目录中生成System.map和u-boot.map两个文件。
System.map文件
Systemp.map部分内容如下,该文件按链接地址由小到大的顺序列出了所有符号。
87800000 T __image_copy_start
87800000 T _start
87800020 T _undefined_instruction
87800024 T _software_interrupt
87800028 T _prefetch_abort
8780002c T _data_abort
87800030 T _not_used
87800034 T _irq
87800038 T _fiq
87800040 T IRQ_STACK_START_IN
87800060 t undefined_instruction
878000c0 t software_interrupt
87800120 t prefetch_abort
87800180 t data_abort
878001e0 t not_used
87800240 t irq
878002a0 t fiq
87800300 T reset
由上面信息可知, _start 符号和__image_copy_start被链接在最前面的地址 0x87800000 ,它是U-Boot的入口。在上电后I.MX6ULL内部的bootrom就会将uboot从内存设备拷贝至0x8780000地址处开始运行。
uboot.map文件
u-boot.map 是 uboot 的映射文件,可以从此文件看到某个文件或者函数链接到了哪个地址。部分内容如下:
链结器命令稿和内存映射
段 .text 的地址设置为 0x87800000
0x0000000000000000 . = 0x0
0x0000000000000000 . = ALIGN (0x4)
.text 0x0000000087800000 0x3fcbc
*(.__image_copy_start)
.__image_copy_start
0x0000000087800000 0x0 arch/arm/lib/built-in.o
0x0000000087800000 __image_copy_start
*(.vectors)
.vectors 0x0000000087800000 0x300 arch/arm/lib/built-in.o
0x0000000087800000 _start
0x0000000087800020 _undefined_instruction
0x0000000087800024 _software_interrupt
0x0000000087800028 _prefetch_abort
0x000000008780002c _data_abort
0x0000000087800030 _not_used
0x0000000087800034 _irq
0x0000000087800038 _fiq
0x0000000087800040 IRQ_STACK_START_IN
arch/arm/cpu/armv7/start.o(.text*)
.text 0x0000000087800300 0xb0 arch/arm/cpu/armv7/start.o
0x0000000087800300 reset
0x0000000087800304 save_boot_params_ret
0x0000000087800340 c_runtime_cpu_setup
0x0000000087800350 save_boot_params
0x0000000087800354 cpu_init_cp15
0x00000000878003a8 cpu_init_crit