2009.11启动过程分析(2)

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

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/780279b2875057836bcd5688171ee09f.html