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指明的地址)

原文地址:https://www.cnblogs.com/zhang2318/p/6078127.html