uboot源码分析(3)
2011-09-09 15:40
316 查看
正式开始了第二阶段:
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, r0, #CFG_MALLOC_LEN // 分配内存区域
186 sub r0, r0, #CFG_GBL_DATA_SIZE
187 #ifdef CONFIG_USE_IRQ
188 sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
189 #endif
190 sub sp, r0, #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, 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语言
编写的函数。
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, r0, #CFG_MALLOC_LEN // 分配内存区域
186 sub r0, r0, #CFG_GBL_DATA_SIZE
187 #ifdef CONFIG_USE_IRQ
188 sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
189 #endif
190 sub sp, r0, #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, 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语言
编写的函数。
相关文章推荐
- UBOOT源码分析1
- uboot源码分析——main_loop
- Uboot 源码分析----启动代码
- 嵌入式linux开发uboot移植(三)——uboot启动过程源码分析
- uboot 源码分析(2)uboot 环境变量实现简析
- uboot源码分析(1)
- uboot移植5-uboot第二阶段源码分析
- UBOOT之源码分析——初始化环境变量
- Uboot 源码分析----代码整体结构分析
- uboot移植与源码分析总结(3)-Serial驱动分析
- uboot 源码分析(2)uboot 环境变量实现简析
- uboot源码分析(2)
- uboot源码分析-运行时内存分布
- Uboot-1.1.2 do_bootm_linux函数源码分析
- ARM汇编中的ldr和adr的区别及其在uboot中相关源码的分析
- UBOOT第二阶段源码分析1
- uboot源码分析(2)
- 三星uboot1.1.6源码分析——start.s(2)--从NAND复制uboot源码到RAM(1)
- Uboot 源码分析----代码整体结构分析
- uboot源码分析——start_armboot