3 SPL 代码分析1(Start.S) armv8架构下的SPL入口函数位于arch/arm/cpu/armv8/start.S文件的_start,它的定义如下: .globl _start
_start:
#ifdef CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK
/*
* Various SoCs need something special and SoC-specific up front in
* order to boot, allow them to set that in their boot0.h file and then
* use it here.
*/
#include <asm/arch/boot0.h>
#else
b reset
#endif
它有两种情况,一种是某些平台会定义自己特殊的启动代码,此处我们看通用的情况,即else的分支中,它直接跳转到了reset处。它的定义如下: reset:
/* Allow the board to save important registers */
b save_boot_params
.globl save_boot_params_ret
save_boot_params_ret:
#ifdef CONFIG_SYS_RESET_SCTRL
# 操作sctrl的值,以配置相关设置
bl reset_sctrl
#endif
此处也是一处跳转指令,它会跳转到save_boot_params处,它的定义如下: WEAK(save_boot_params)
b save_boot_params_ret /* back to my caller */
ENDPROC(save_boot_params)
我们看到它的前面加了WEAK关键字,该关键字标识其是一个弱符号,用法为若其它的地方定义了同名的函数或全局变量,则会使用重定义的值,否则就使用WEAK标号中的定义。实际上它是一个很有用的特性,如我们可以为某个函数定义一个默认的定义,并将其用WEAK关键字修饰,当调用该函数的用户**其使用自己定义的特殊实现时,就可以在其它的文件中重新定义一个非WEAK的同名函数,此时链接器链接时就会链接新的定义,而自动忽略掉用WEAK修饰的定义,从而可以实现函数功能的扩展,或者用于一些debug操作等。此处我们只看默认定义,它什么也不做,继续跳转回了原来的位置save_boot_params_ret。 其后根据是否配置了CONFIG_SYS_RESET_SCTRL参数决定是否执行reset_sctrl的内容。我们看下它的实现如下: #ifdef CONFIG_SYS_RESET_SCTRL
reset_sctrl:
switch_el x1, 3f, 2f, 1f
3:
mrs x0, sctlr_el3
b 0f
2:
mrs x0, sctlr_el2
b 0f
1:
mrs x0, sctlr_el1
0:
ldr x1, =0xfdfffffa
and x0, x0, x1
switch_el x1, 6f, 5f, 4f
6:
msr sctlr_el3, x0
b 7f
5:
msr sctlr_el2, x0
b 7f
4:
msr sctlr_el1, x0
7:
dsb sy
isb
b __asm_invalidate_tlb_all
ret
#endif
|