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

一.  uboot启动流程涉及函数

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

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

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

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

  二.  _main汇编函数

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

114 adr lr, here
115 ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */
116 add lr, lr, r0
117 #if defined(CONFIG_CPU_V7M)
118 orr lr, #1 /* As required by Thumb-only */
119 #endif
120 ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */
121 b relocate_code
122 here:
123 /*
124 * now relocate vectors
125 */
126
127 bl relocate_vectors
128
129 /* Set up final (full) environment */
130
131 bl c_runtime_cpu_setup /* we still call old routine here */
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 函数,如下是继以上代码:

131 bl c_runtime_cpu_setup /* we still call old routine here */
132 #endif
133 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)
134 # ifdef CONFIG_SPL_BUILD
135 /* Use a DRAM stack for the rest of SPL, if requested */
136 bl spl_relocate_stack_gd
137 cmp r0, #0
138 movne sp, r0
139 movne r9, r0
140 # endif
141 ldr r0, =__bss_start /* this is auto-relocated! */
142
143 #ifdef CONFIG_USE_ARCH_MEMSET
144 ldr r3, =__bss_end /* this is auto-relocated! */
145 mov r1, #0x00000000 /* prepare zero to clear BSS */
146
147 subs r2, r3, r0 /* r2 = memset len */
148 bl memset
149 #else
150 ldr r1, =__bss_end /* this is auto-relocated! */
151 mov r2, #0x00000000 /* prepare zero to clear BSS */
152
153 clbss_l:cmp r0, r1 /* while not at end of BSS */
154 #if defined(CONFIG_CPU_V7M)
155 itt lo
156 #endif
157 strlo r2, [r0] /* clear 32-bit BSS word */
158 addlo r0, r0, #4 /* move to next */
159 blo clbss_l
160 #endif

141~159 行,清除 BSS 段。

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

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

162 #if ! defined(CONFIG_SPL_BUILD)
163 bl coloured_LED_init
164 bl red_led_on
165 #endif
166 /* call board_init_r(gd_t *id, ulong dest_addr) */
167 mov r0, r9 /* gd_t */
168 ldr r1, [r9, #GD_RELOCADDR] /* dest_addr */
169 /* call board_init_r */
170 #if defined(CONFIG_SYS_THUMB_BUILD)
171 ldr lr, =board_init_r /* this is auto-relocated! */
172 bx lr
173 #else
174 ldr pc, =board_init_r /* this is auto-relocated! */
175 #endif
176 /* we should not return here. */
177 #endif
178
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 个函数都是干啥的。

猜你喜欢

转载自blog.csdn.net/wojiaxiaohuang2014/article/details/133437881