14.3.5 relocate标号

14.3.5  relocate标号

relocate部分的代码负责把U-Boot Stage2的代码从Flash存储器加载到内存,代码     如下:

 

163 #ifndef CONFIG_SKIP_RELOCATE_UBOOT

164 relocate:       /* relocate U-Boot to RAM     */

165   adr r0, _start    /* r0 <- current position of code   */   
                                                //
获取当前代码存放地址

166   ldr r1, _TEXT_BASE    /* test if we run from flash or RAM */
                                                //
获取内存存放代码地址

167   cmp     r0, r1                  /* don't reloc during debug         */
                                                //
检查是否需要加载

168   beq     stack_setup

169

170   ldr r2, _armboot_start                // 获取stage2代码存放地址

171   ldr r3, _bss_start                    // 获取内存代码段起始地址

172   sub r2, r3, r2    /* r2 <- size of armboot            */
                                                //
计算stage2代码长度

173   add r2, r0, r2    /* r2 <- source end address         */
                                                //
计算stage2代码结束地址

174

175 copy_loop:

176   ldmia r0!, {r3-r10}   /* copy from source address [r0]    */
                                                //
Flash复制代码到内存

177   stmia r1!, {r3-r10}   /* copy to   target address [r1]    */

178   cmp r0, r2      /* until source end addreee [r2]    */

179   ble copy_loop

180 #endif  /* CONFIG_SKIP_RELOCATE_UBOOT */

181

182   /* Set up the stack               */
                                                //
在内存中建立堆栈

183 stack_setup:

184   ldr r0, _TEXT_BASE    /* upper 128 KiB: relocated uboot   */

185   sub r0, r0, #CFG_MALLOC_LEN /* malloc area     */  // 分配内存区域

186   sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo   */

187 #ifdef CONFIG_USE_IRQ

188   sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)

189 #endif

190   sub sp, r0, #12   /* leave 3 words for abort-stack    */

191

192 clear_bss:                                  // 初始化内存bss段内容为0

193   ldr r0, _bss_start    /* find start of bss segment        */
                                                //
查找bss段起始地址

194   ldr r1, _bss_end    /* stop here  */  // 查找bss段结束地址

195   mov   r2, #0x00000000   /* clear   */   // 清空bss段内容

196

197 clbss_l:str r2, [r0]    /* clear loop...                    */

198   add r0, r0, #4

199   cmp r0, r1

200   ble clbss_l

223   ldr pc, _start_armboot // 设置程序指针为start_armboot()函数地址

224

225 _start_armboot: .word start_armboot

 

程序首先在165168行检查当前是否在内存中执行代码,根据结果决定是否需要从Flash存储器加载代码。程序通过获取_start_TEXT_BASE所在的地址比较,如果地址相同说明程序已经在内存中,无须加载。

%提示:24章介绍Flash存储器的时候会介绍一种NOR类型Flash存储器,可以像使用内存一样直接执行程序。从S3C2440A手册的内存映射图中可以看出,NOR Flash被映射到地址0开始的内存空间。

程序第170173行计算要加载的Stage2代码起始地址和长度,然后在第176179行循环复制Flash的数据到内存,每次可以复制8个字长的数据。Stage2程序复制完毕后,程序第184190行设置系统堆栈,最后在第193200行清空内存bss段的内容。

relocate程序最后在223行设置程序指针寄存器为start_armboot()函数地址,程序跳转到Stage2部分执行。请注意第225行的定义,_start_armboot全局变量的值是C语言函数start_armboot()函数的地址,使用这种方式可以在汇编中调用C语言编写的函数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值