fig.mk中指定的值为0x33F80000,即u-boot在把代码拷贝到RAM中去 执行的代码段的开始) */
ldr r1, _TEXT_BASE /* 测试判断是从Flash启
动,还是RAM */
/* 此句执行的结果r1始终是0x33F80000,因为此值是链接指定的 */
cmp r0, r1 /* 比较r0和r1,
调试的时候不要执行重定位 */(引用《u-boot.lds解析》)
所以说实际链接时,都是以_TEXT_BASE为基地址,但是运行时会根据现在代码所处的位置去复制uboot代码到内存(因为在复制到内存之前都是用相对地址的),如果在内存,就直接接着运行即可.具体请参考u-boot根目录下的config.mk.
顺着这个config.lds文件,就开始执行u-boot-1.3.4\cpu\arm920t\start.S
它里面大概执行流程是
(1) CPU为SVC模式
(2) 定义中断向量表
(3) 关闭中断 (因为uboot不需要使用中断)
(4) 底层初始化:两个函数cpu_init_crit和lowlevel_init
cpu_init_crit是禁止MMU和CACHE,为什么?因为如果你不禁止,有些数据会残留在cache上,会造成脏数据(《具体也可以参考ARM体系结构与编程》)
lowlevel_init主要是定义部分寄存器以及初始化SDRAM
(5) 然后把代码拷贝到内存中(没修改时为下面代码,修改后使用自 移植的)
#ifndefCONFIG_SKIP_RELOCATE_UBOOT
relocate: /* relocate U-Boot to RAM */
adr r0,_start /* r0 <- currentposition of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't relocduring debug */
beq stack_setup
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 /* r2 <- size of armboot */
add r2, r0, r2 /* r2 <- source end address */
copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
#endif /*CONFIG_SKIP_RELOCATE_UBOOT */
(6) 初始化堆栈(其实就是在内存中开辟一个区域,用于保存数据,其实是栈,经典映射图如下图)
(7) 调用C语言函数入口,start_armboot