3、复制stage2代码到RAM空间
这里将u-boot的代码(实际包括第一、二阶段)都复制到SDRAM中,这在cpu\arm_cortexa8中start.S中完成,这一步是u-boot第一阶段的核心所在,因为它实际上完成将代码拷贝到u-boot执行的链接地址处,在此之后的变量就可以进行正常读写,前面的代码必须是位置无关代码(只能读操作不能写操作)。
relocate: /*将x-loader复制到RAM中 */
adr r0, _start /* r0:当前代码的开始地址 */
ldr r1, _TEXT_BASE /* r1:代码段的链接地址 */
cmp r0, r1 /* 测试是否需要复制(SRAM,SDRAM,NOR FLAHS不需要复制)
beq stack_setup /*直接跳到栈初始化部分) */
ldr r2, _armboot_start /*_armboot_start在前面定义,第一条指令地址*/
ldr r3, _bss_start /*链接脚本x-loader.lds中定义,是代码段的结束地址*/
sub r2, r3, r2 /* r2 :代码段长度 */
add r2, r0, r2 /* r2:SRAM上代码段的结束地址 */
copy_loop:
ldmia r0!, {r3-r10} /*从地址[r0]处获得数据 */
stmia r1!, {r3-r10} /*复制到地址[r1]处 */
cmp r0, r2 /*判断是否复制完毕 */
ble copy_loop
4、设置堆栈
栈的设置灵活性很大,只要让sp寄存器指向一段没有使用的内存即可。
/* Set up the stack */
stack_setup:
ldr r0, _TEXT_BASE /*_TEXT_BASE代码段的开始地址 */
sub sp, r0, #128 /*为 abort-栈保留32字节 */
and sp, sp, #~7 /* 8字节对齐 */
5、跳转到stage2的入口点
在跳转之前,还要清除BSS段(初始值为0、无初始值的全局变量、静态变量放在BSS段),代码如下:
clear_bss:
ldr r0, _bss_start /* bss段的开始地址 */
ldr r1, _bss_end /* bss段的结束地址,它的值在链接脚本中定义*/
mov r2, #0x00000000 /* clear value */
clbss_l:
str r2, [r0] /*往bss段内写入0值 */
cmp r0, r1 /*are we at the end yet */
add r0, r0, #4 /* increment clearindex pointer */
bne clbss_l /* keep clearing till atend */
ldr pc, _start_armboot /*向C函数入口跳转 */
_start_armboot: .word start_armboot