正式开始了第二阶段:
relocate部分的代码负责把U-Boot Stage2的代码从Flash存储器加载到内存,代码如下:
- 163?#ifndef?CONFIG_SKIP_RELOCATE_UBOOT ?
-
164?relocate:???????
- 165???adr? r0,? _start???? ?? ?
- ?????????????????????? ????????????????????????? ???????? //?获取当前代码存放地址 ?00000000
- 166???ldr ?r1,_TEXT_BASE????????????????? ?
- ??????????????????????????????????????????????? ???????????????? //?获取内存存放代码地址 ?33f80000
-
167???cmp?????r0,? r1?????????????????? ???????
-
??????????????????????????????????????????????? ?????????????? //地址相同说明程序已经在内存中则不需要加载 ?
- 168???beq?????stack_setup ?
- 169??//开始加载
-
170???ldr? r2,_armboot_start???????????????//?获取stage2代码存放地址 ?
- 171???ldr r3,? _bss_start??????????????????????? //?获取内存代码段起始地址 ?
- 172???sub ?r2,?r3,r2?? ??????? ?? ?
- ??????????????????????????????????????????????? ????????????????// 不包括向量表,U-BOOT的整个大小
- 173???add ?r2,?r0,?r2??? ?? ?
- ??????????????????????33f80000 size ??????? //?计算stage2代码结束地址?
-
174? ?
- 175?copy_loop: ?
- 176???ldmia ?r0!,?{r3-r10}?? ? ?
-
????????????????????????????????????????????????????????? ? //?从Flash复制代码到内存 ?
- 177???stmia r1!,?{r3-r10}??? ?
- 178???cmp? r0,?r2???? ??? ?
- 179???ble ?copy_loop ?
- 180?#endif? ? ?
-
181? ?
-
182?? ?? ?
-
??????//?在内存中建立堆栈 ?
- 183?stack_setup: ?
- 184???ldr?r0,?_TEXT_BASE??? ? ?????????? ? ?
- 185???sub?r0,?#CFG_MALLOC_LEN ? ?? ??//?分配内存区域 ?
- 186???sub?r0,?#CFG_GBL_DATA_SIZE ? ?
-
187?#ifdef?CONFIG_USE_IRQ ?
- 188???sub?r0,?#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) ?
-
189?#endif ?
- 190???sub?sp,?#12??? ? ?
-
191? ?
-
192?clear_bss:???????????????????????????????????? ?//?初始化内存bss段内容为0 ?
- 193???ldr?r0,?_bss_start???? ? ?
-
???????????????????????????????????????????????? ????? //?查找bss段起始地址 ?
- 194???ldr? r1,? _bss_end??? ? ??//?查找bss段结束地址 ?
- 195???mov???r2,? #0x00000000?????????????//?清空bss段内容 ?
-
196? ?
- 197? clbss_l: str?r2,?[r0]???? ?? ?
-
198???add ?r0,?#4 ?
-
199???cmp ?r0,?r1 ?
-
200???ble? clbss_l ?
- 223???ldr? pc,? _start_armboot?? ?//?设置程序指针为start_armboot()函数地址 ?
-
224? ?
-
225?_start_armboot:
-
.word?start_armboot //这里是个C的函数名字,也就是入口地址
代码解释:
??????? 程序首先在165~168行检查当前是否在内存中执行代码,根据结果决定是否需要从Flash存储器加载代码。程序通过获取_start和_TEXT_BASE所在的地址比较,如果地址相同说明程序已经在内存中,无须加载。
?
??????? 程序第170~173行计算要加载的Stage2代码起始地址和长度,然后在第176~179行循环复制Flash的数据到内存,每次可以复制8个字长的数据。
?
??????? Stage2程序复制完毕后,程序第184~190行设置系统堆栈,最后在第193~200行清空内存bss段的内容。
?
??????? relocate程序最后在223行设置程序指针寄存器为start_armboot()函数地址,程序跳转到Stage2部分执行。请注意第 225行的定义,_start_armboot全局变量的值是C语言函数start_armboot()函数的地址,使用这种方式可以在汇编中调用C语言 编写的函数。
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|