• uboot启动流程-涉及_main汇编函数


    一.  uboot启动流程涉及函数

    本文继续分析一下 save_boot_params_ret调用的函数:_main汇编函数。

    分析 _main函数的下半部分代码。

    本文继之前文章的学习,地址如下:

    uboot启动流程-涉及_main汇编函数-CSDN博客

      二.  _main汇编函数

    下面继续分析 _main函数,_main函数的部分代码如下:

    1. 114 adr lr, here
    2. 115 ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */
    3. 116 add lr, lr, r0
    4. 117 #if defined(CONFIG_CPU_V7M)
    5. 118 orr lr, #1 /* As required by Thumb-only */
    6. 119 #endif
    7. 120 ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
    8. 121 b relocate_code
    9. 122 here:
    10. 123 /*
    11. 124 * now relocate vectors
    12. 125 */
    13. 126
    14. 127 bl relocate_vectors
    15. 128
    16. 129 /* Set up final (full) environment */
    17. 130
    18. 131 bl c_runtime_cpu_setup /* we still call old routine here */
    19. 132 #endif

    114 行,设置 lr 寄存器为 here ,这样后面执行其他函数返回的时候就返回到了第 122 行的 here 位置处。
    115 ,读取 gd->reloc_off 的值复制给 r0 寄存器, GD_RELOC_OFF=68
    116 行, lr 寄存器的值加上 r0 寄存器的值,重新赋值给 lr 寄存器。
    因为接下来要重定位 代码。也就是把代码拷贝到新的地方去 ( 现在的 uboot 存放的起始地址为 0X87800000 ,下面要 uboot 拷贝到 DDR 最后面的地址空间出,将 0X87800000 开始的内存空出来 ) ,其中就包括 here ,因此, lr 中的 here 要使用重定位后的位置。
    120 行,读取 gd->relocaddr 的值赋给 r0 寄存器,此时 r0 寄存器就保存着 uboot 要拷贝 的目的地址,为 0X9FF47000 GD_RELOCADDR=48
    121 行,调用 relocate_code 函数,也就是代码重定位函数,此函数负责将 uboot 拷贝到新 的地方去,此函数定义在文件 arch/arm/lib/relocate.S 中稍后会详细分析此函数。
    127 行,调用 relocate_vectors 函数,对中断向量表做重定位, 此函数定义在文件 arch/arm/lib/relocate.S 中,稍后会详细分析此函数。

    继续分析_main 函数,如下是继以上代码:

    1. 131 bl c_runtime_cpu_setup /* we still call old routine here */
    2. 132 #endif
    3. 133 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)
    4. 134 # ifdef CONFIG_SPL_BUILD
    5. 135 /* Use a DRAM stack for the rest of SPL, if requested */
    6. 136 bl spl_relocate_stack_gd
    7. 137 cmp r0, #0
    8. 138 movne sp, r0
    9. 139 movne r9, r0
    10. 140 # endif
    11. 141 ldr r0, =__bss_start /* this is auto-relocated! */
    12. 142
    13. 143 #ifdef CONFIG_USE_ARCH_MEMSET
    14. 144 ldr r3, =__bss_end /* this is auto-relocated! */
    15. 145 mov r1, #0x00000000 /* prepare zero to clear BSS */
    16. 146
    17. 147 subs r2, r3, r0 /* r2 = memset len */
    18. 148 bl memset
    19. 149 #else
    20. 150 ldr r1, =__bss_end /* this is auto-relocated! */
    21. 151 mov r2, #0x00000000 /* prepare zero to clear BSS */
    22. 152
    23. 153 clbss_l:cmp r0, r1 /* while not at end of BSS */
    24. 154 #if defined(CONFIG_CPU_V7M)
    25. 155 itt lo
    26. 156 #endif
    27. 157 strlo r2, [r0] /* clear 32-bit BSS word */
    28. 158 addlo r0, r0, #4 /* move to next */
    29. 159 blo clbss_l
    30. 160 #endif

    141~159 行,清除 BSS 段。

    131 行,调用函数 c_runtime_cpu_setup ,此函数定义在文件 arch/arm/cpu/armv7/start.S 中,函数内容如下: 应该是关闭 I-cache的功能:
    1. 77 ENTRY(c_runtime_cpu_setup)
    2. 78 /*
    3. 79 * If I-cache is enabled invalidate it
    4. 80 */
    5. 81 #ifndef CONFIG_SYS_ICACHE_OFF
    6. 82 mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
    7. 83 mcr p15, 0, r0, c7, c10, 4 @ DSB
    8. 84 mcr p15, 0, r0, c7, c5, 4 @ ISB
    9. 85 #endif
    10. 86
    11. 87 bx lr
    12. 88
    13. 89 ENDPROC(c_runtime_cpu_setup)

    继续分析_main 函数,如下是继以上代码:

    1. 162 #if ! defined(CONFIG_SPL_BUILD)
    2. 163 bl coloured_LED_init
    3. 164 bl red_led_on
    4. 165 #endif
    5. 166 /* call board_init_r(gd_t *id, ulong dest_addr) */
    6. 167 mov r0, r9 /* gd_t */
    7. 168 ldr r1, [r9, #GD_RELOCADDR] /* dest_addr */
    8. 169 /* call board_init_r */
    9. 170 #if defined(CONFIG_SYS_THUMB_BUILD)
    10. 171 ldr lr, =board_init_r /* this is auto-relocated! */
    11. 172 bx lr
    12. 173 #else
    13. 174 ldr pc, =board_init_r /* this is auto-relocated! */
    14. 175 #endif
    15. 176 /* we should not return here. */
    16. 177 #endif
    17. 178
    18. 179 ENDPROC(_main)
    167 行,设置函数 board_init_r 的两个参数,函数 board_init_r 声明如下:
    board_init_r(gd_t *id, ulong dest_addr) 
    第一个参数是 gd ,因此读取 r9 保存到 r0 里面。
    168 行,设置函数 board_init_r 的第二个参数是目的地址,因此 r1= gd->relocaddr
    174 行、调用函数 board_init_r ,此函数定义在文件 common/board_r.c 中,稍后会详细的
    分析此函数。

     

    这个就是_main 函数的运行流程。

    _main 函数里面调用了 board_init_frelocate_code、relocate_vectors board_init_r 4 个函数,接下来依次看一下这 4 个函数都是干啥的。

  • 相关阅读:
    基于Python通信程序的设计与实现
    深入理解Nginx线程池【内附原理讲解以及源码分析】
    哈希算法--MD5算法
    23.11.19日总结(vue2和vue3的区别,项目中期总结)
    【Python机器学习】零基础掌握QuadraticDiscriminantAnalysis判别分析
    我为什么使用Linux做开发
    刷题笔记之二(字符串中找出连续最长的数字串+数组中出现次数超过一半的数字+另类加法+计算糖果+进制转换)
    20240418金融读报:银行参考汇丰全球化布局&银行全球化布局现有路径&再读金融助力新型工业化
    如何解决找不到msvcr100.dll问题,msvcr100.dll丢失的多种修复方案
    png图片自动转ttf字体(使用python实现)
  • 原文地址:https://blog.csdn.net/wojiaxiaohuang2014/article/details/133437881