uboot源码分析(3)

来源:互联网 发布:项目数据分析师报名 编辑:程序博客网 时间:2024/05/04 22:04

正式开始了第二阶段:

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

  1. 163 #ifndef CONFIG_SKIP_RELOCATE_UBOOT  
  2. 164 relocate      
  3. 165   adr  r0,  _start         
  4.                                                           // 获取当前代码存放地址  00000000
  5. 166   ldr  r1, _TEXT_BASE                   
  6.                                                                  // 获取内存存放代码地址  33f80000
  7. 167   cmp     r0,  r1                          
  8.                                                                //地址相同说明程序已经在内存中则不需要加载  
  9. 168   beq     stack_setup  
  10. 169   //开始加载
  11. 170   ldr  r2, _armboot_start               // 获取stage2代码存放地址  
  12. 171   ldr r3,  _bss_start                        // 获取内存代码段起始地址  
  13. 172   sub  r2,  r3, r2               
  14.                                                                 // 不包括向量表,U-BOOT的整个大小
  15. 173   add  r2,  r0,  r2        
  16.                       33f80000 size         // 计算stage2代码结束地址 
  17. 174   
  18. 175 copy_loop:  
  19. 176   ldmia  r0!,  {r3-r10}      
  20.                                                             // 从Flash复制代码到内存  
  21. 177   stmia r1!,  {r3-r10}     
  22. 178   cmp  r0,  r2          
  23. 179   ble  copy_loop  
  24. 180 #endif     
  25. 181   
  26. 182       
  27.       // 在内存中建立堆栈  
  28. 183 stack_setup:  
  29. 184   ldr r0, _TEXT_BASE                    
  30. 185   sub r0, r0, #CFG_MALLOC_LEN        // 分配内存区域  
  31. 186   sub r0, r0, #CFG_GBL_DATA_SIZE    
  32. 187 #ifdef CONFIG_USE_IRQ  
  33. 188   sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)  
  34. 189 #endif  
  35. 190   sub sp, r0, #12       
  36. 191   
  37. 192 clear_bss:                                      // 初始化内存bss段内容为0  
  38. 193   ldr r0, _bss_start        
  39.                                                        // 查找bss段起始地址  
  40. 194   ldr  r1,  _bss_end        // 查找bss段结束地址  
  41. 195   mov   r2,  #0x00000000             // 清空bss段内容  
  42. 196   
  43. 197  clbss_l: str r2, [r0]         
  44. 198   add  r0,  r0,  #4  
  45. 199   cmp  r0,  r1  
  46. 200   ble  clbss_l  
  47. 223   ldr  pc,  _start_armboot    // 设置程序指针为start_armboot()函数地址  
  48. 224   
  49. 225 _start_armboot:
  50. .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语言 编写的函数。


原创粉丝点击