** _start会调用reset函数进入OP-TEE OS的启动过程**。
由于对称多处理(Symmetr ical Multi-Processing, SMP)架构的原因,在reset函数中会对主核和从核进行不同的启动操作,分别调用reset_primary函数和reset_secondary函数来完成。
reset函数是主核和从核启动的第一个函数,该函数的执行流程如图所示。
reset函数执行流程
进入到reset函数后, 系统会将_start的地址写入VBAR寄存器作为中断向量表的起始地址使用 ,
在启动从核时, 从核知道会到该地址去获取应该执行代码来完成从核的启动 。整个reset函数的内容和注释如下:
LOCAL_FUNC reset , :
UNWIND( .fnstart)
UNWIND( .cantunwind)
bootargs_entry //获取启动带入的参数,主要是启动地址、device tree地址等
/* 使能对齐检查并禁用数据和指令缓存 */
read_sctlr r0 //读取sctlr中的数据,获取当前CPU控制寄存器中的值
#if defined(CFG_SCTLR_ALIGNMENT_CHECK)
orr r0, r0, #SCTLR_A //设定对齐校验
#else
bic r0, r0, #SCTLR_A
#endif
bic r0, r0, #SCTLR_C //关闭数据cache
bic r0, r0, #SCTLR_I //关闭指令cache
#if defined(CFG_HWSUPP_MEM_PERM_WXN) && defined(CFG_CORE_RWDATA_NOEXEC)
orr r0, r0, #(SCTLR_WXN | SCTLR_UWXN)
#endif
write_sctlr r0 //将r0写入到sctlr中,用于关闭cache
isb
/* 早期ARM核安全监控模式态的特殊配置 */
bl plat_cpu_reset_early //执行CPU早期初始化
ldr r0, =_start //设定r0寄存器的值为_start函数的地址
write_vbar r0 //将_start函数的地址写入VBAR寄存器中,用于启动时使用
#if defined(CFG_WITH_ARM_TRUSTED_FW)
b reset_primary //支持ATF时跳转到reset_primary中执行
#else
bl get_core_pos //判定当前CPU CORE的编号
cmp r0, #0 //将获得的CPU编号与0对比
beq reset_primary //如果当前core是主核,则使用reset_primary进行初始化
b reset_secondary //如果当前core是从核,则使用reset_secondary进行初始化
#endif
UNWIND( .fnend)
END_FUNC reset
plat_cpu_reset_early函数将会设定SCR寄存器中的安全标志位 ,用于标记当前CPU是处于安全世界状态中,并且将_start地址写入VBAR寄存器,用于在需要启动从核时系统能找到启动代码的入口地址,
reset_primary函数是主核启动代码的入口函数,该函数将会启动主核的基本初始化、配置运行环境,然后再开始执行唤醒从核的操作。
全部0条评论
快来发表一下你的评论吧 !