【版权申明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)
start.S的流程
.globl _start
_start:
# 在上电或者重启后, CPU执行的第一条指令就是reset, 所以会直接跳到reset函数处.
# reset函数中实现了硬件的初始化
b reset
......
_start_armboot:
.word start_armboot
reset
# 汇编中可以使用ENTRY和ENDPROC两个宏来定义一个函数, 如下的save_boot_params
ENTRY(save_boot_params)
# 跳转到save_boot_params_ret函数, 其实就是调回reset函数并继续执行.
b save_boot_params_ret @ back to my caller
ENDPROC(save_boot_params)
# .weak是一个伪指令(上一章忘讲了), 它用于声明一个函数, 但如果存在同名的函数, 他的优先级会更低, 即不会调用到它.
.weak save_boot_params
reset:
# reset首先是跳转到save_boot_params, 如上代码片段可见
b save_boot_params
save_boot_params_ret: #修改cpsr寄存器, 设置处理器进入svc模式, 并且关掉irq和fiq.
mrs r0, cpsr
and r1, r0, #0x1f @ mask mode bits
teq r1, #0x1a @ test for HYP mode
bicne r0, r0, #0x1f @ clear all mode bits
orrne r0, r0, #0x13 @ set SVC mode
orr r0, r0, #0xc0 @ disable FIQ and IRQ
msr cpsr,r0
......
/* init PLL/DDRC/pin mux/... */
......
mov pc, r1 /* return to bootrom */
reset之后的执行流程
将运行代码拷贝到DDR中, 并开始在DDR中运行
/* normal_start_flow */
......
/* check_boot_type */
......
/* ddr_init */
......
/* check_boot_mode */
......
/* emmc_boot */
ldr r1, =__image_copy_start
ldr r2, =__bss_start
sub r1, r2, r1
bl emmc_boot_read
b relocate
relocate:
ldr r0, =_start_armboot
ldr pc, [r0]
上面的代码跳转到_start_armboot后调用start_armboot, 至此start.S里面的逻辑运行完毕, 走到了C语言阶段的startup.c:68:void start_armboot(void)当中.