赞
踩
编译过uboot之后会在uboot根目录下生成u-boot.lds文件,这是链接程序的脚本,从这里找程序的入口。重点代码如下:
ENTRY(_start) //当前代码入口点“_start”(在arch/arm/lib/vectors.S中定义,后面就是中断向量表)
.text :
{
*(.__image_copy_start)
*(.vectors) //vectors段保存中断向量表
arch/arm/cpu/armv7/start.o (.text*) //将arch/arm/cpu/armv7/start.s编译出的.o放到中断向量表后面
*(.text*) //其它代码段放在这
}
打开u-boot.map(该文件为uboot的映射文件,可以看到哪个文件或者函数链接到的地址),vscode中搜索,可以看到__image_copy_start链接到0X87800000也是.text和vectors段的起始地址。一些和地址有关的变量值如下:
__image_copy_start 0x87800000 uboot 拷贝的首地址
__image_copy_end 0x8785dd54 uboot 拷贝的结束地址
__rel_dyn_start 0x8785dd54 .rel.dyn 段起始地址
__rel_dyn_end 0x878668f4 .rel.dyn 段结束地址
_image_binary_end 0x878668f4 镜像结束地址
__bss_start 0x8785dd54 .bss 段起始地址
__bss_end 0x878a8e74 .bss 段结束地址
“_start”在arch/arm/lib/vectors.S中,其中“b reset”开始跳转到reset函数(arch/arm/cpu/armv7/start.S),reset函数中“b save_boot_params”跳转到save_boot_params函数。再由“b save_boot_params_ret”跳转,save_boot_params_ret函数进行一些对于CPU的设置,调用了一些函数比如cpu_init_crit,_main等,cpu_init_crit其内部调用了lowlevel_init。
lowlevel_init在arch/arm/cpu/armv7/lowlevel_init.S定义,重要代码:
//设置SP指针指向CONFIG_SYS_INIT_SP_ADDR(在include/configs/mx6ullevk.h)
//其中定义了一些变量,比如IMX6ULL内部ocram的首地址和大小
ldr sp, =CONFIG_SYS_INIT_SP_ADDR
//对sp指针做8字节对齐处理
bic sp, sp, #7
//sp指针减去GD_SIZE(248)
sub sp, sp, #GD_SIZE
bic sp, sp, #7
mov r9, sp //将sp地址保存在r9寄存器
//s_init会判断CPU类型,对于IMX6ULL返回空
bl s_init
来源于arch/arm/lib/crt0.S,重要代码:
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) //设置sp指向0X0091FF00 //调用函数,参数为r0中的值=0X0091FF00 //作用是留出早期的malloc内存区域和gd内存区域 //返回值为新的top值==0X0091FA00 bl board_init_f_alloc_reserve //用于初始化 gd,其实就是清零处理。 //设置了early malloc起始地址=0X0091FB00 bl board_init_f_init_reserve //初始化DDR,定时器,完成代码拷贝等 //初始化gd的各个成员变量,这些成员变量使得uboot自己重定位到DRAM最后的地址区域给Linux腾出空间,生成一个内存“分配图” bl board_init_f //将uboot拷贝到新的地址 b relocate_code //对中断向量表进行重定位 bl relocate_vectors //清除BSS段,设置board_init_r等 bl c_runtime_cpu_setup
board_init_f最终内存分配结果:
略,以后再看吧
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。