UBoot源码分析之----代码重定位
board_init_f函数的最后返回到relocate_code,调用该函数的原型是
Relocate_code(addr_sp,id,addr),再讲一下三个参数的意义:
addr_sp是地址空间里面堆栈的首地址
id是存储gd_t类型全局参数的首地址
addr是uboot的重定位地址,也就是加载地址
这三个参数的值都是在board_init_f函数里面定义好了的
现在跳到arch/arm/cpu/armv7/start.s中的relocate_code代码标号处。
.globl relocate_code relocate_code: mov r4, r0 /*save addr_sp */ mov r5, r1 /*save addr of gd */ mov r6, r2 /*save addr of destination */ 这里面r0,r1和r2分别对应上面所讲的三个参数 r0 – addr_sp r1 – id r2 – addr /* Setup the stack*/ stack_setup: mov sp,r4 设置堆栈指针 adr r0,_start #ifndef CONFIG_PRELOADER cmp r0,r6 beq clear_bss /*skip relocation*/ #endif
adr 指令见博文 LDR和ADR彻底详解
mov r1,r6 /*r1<-scratch for copy_loop*/ ldr r2,_TEXT_BASE ldr r3,_bss_start_ofs add r2,r0,r3 /*r2<-source end address*/ copy_loop: ldmia r0!,{r9-r10} /*copy from source address [r0]*/ stmia r1!,{r9-r10} /**copy to target address[r1]/ cmp r0,r2 /*until source end address[r2]*/ blo copy_loop
_TEXT_BASE标号处存放的是CONFIG_SYS_TEXT_BAE,改变量定义在/board/samsung/smdk4212/config.mk值为0xc3e0_0000,不过在这段程序中好像没什么用,addr r2,r0,r3 使得r2 =r3(因为r0=0),即BSS段的开始地址,也就是代码段的结束地址。整个copy_loop循环就是将uboot代码拷贝到重定位地址处(即addr指明的地址)