1,分析startup.s 启动流程
pc 指针指向异常向量表的首地址及 reset 函数
FUNC_DEF(vector)
B reset
LDR PC, undefineEntry
LDR PC, swiEntry
LDR PC, prefetchEntry
LDR PC, abortEntry
LDR PC, reserveEntry
LDR PC, irqEntry
LDR PC, fiqEntry
FUNC_END()
reset 函数分析
1)第一步 设置工作模式为 SVC模式并关闭所有中断;
2)第二步 初始化堆栈,其中分SMP和AMP模式;
3)第三步 关闭 D-Cache(回写并无效),关闭 I-Cache(无效),无效并关闭分支预测,关闭 MMU(无效 TLB);
4)第四步 初始化data段;
5)第五步 清零bss段;
6)第六步 调用 targetInit 函数 初始化时钟,一般情况下时钟基本上在uboot 时已经初始化了,所以基本上为空函数;
7)进入内核初始化函数,开始进行内核资源初始化;
;/*********************************************************************************************************
; 初始化各处理器模式的堆栈指针
;*********************************************************************************************************/
FUNC_DEF(armInitSP)
MSR CPSR_c, #(SVC32_MODE | DIS_INT)
MOV SP, R0
SUB R0, R0, #SVC_STACK_SIZE
MSR CPSR_c, #(SYS32_MODE | DIS_INT)
MOV SP, R0
SUB R0, R0, #SYS_STACK_SIZE
MSR CPSR_c, #(FIQ32_MODE | DIS_INT)
MOV SP, R0
SUB R0, R0, #FIQ_STACK_SIZE
MSR CPSR_c, #(IRQ32_MODE | DIS_INT)
MOV SP, R0
SUB R0, R0, #IRQ_STACK_SIZE
MSR CPSR_c, #(UND32_MODE | DIS_INT)
MOV SP, R0
SUB R0, R0, #UND_STACK_SIZE
MSR CPSR_c, #(ABT32_MODE | DIS_INT)
MOV SP, R0
SUB R0, R0, #ABT_STACK_SIZE
MSR CPSR_c, #(SVC32_MODE | DIS_INT)
BX LR
FUNC_END()
FUNC_DEF(reset)
;/*********************************************************************************************************
; 进入 SVC32 模式(关中断)
;*********************************************************************************************************/
MSR CPSR_c, #(SVC32_MODE | DIS_INT)
;/*********************************************************************************************************
; 初始化堆栈
;*********************************************************************************************************/
#if LW_CFG_SMP_EN > 0
BL archMpCur
LDR R1 , =__stack_end ;/* 栈区顶端地址 */
LINE_LABEL(0)
CMP R0, #0
SUBNE R1, R1, #CPU_STACKS_SIZE
SUBNE R0, R0, #1
BNE 0b
#else
LDR R1 , =__stack_end ;/* 栈区顶端地址 */
#endif
MOV R0, R1
BL armInitSP
;/*********************************************************************************************************
; 如果不是 Primary CPU, 则跳转到 secondaryCpuResetEntry
;*********************************************************************************************************/
#if LW_CFG_SMP_EN > 0
BL archMpCur
CMP R0, #0
BLNE secondaryCpuResetEntry
#endif
;/*********************************************************************************************************
; 关闭 D-Cache(回写并无效)
; 关闭 I-Cache(无效)
; 无效并关闭分支预测
; 关闭 MMU(无效 TLB)
;*********************************************************************************************************/
BL armDCacheV7ClearAll
BL armDCacheV7Disable
BL armICacheInvalidateAll
BL armICacheDisable
BL armBranchPredictorInvalidate
BL armBranchPredictionDisable
BL armMmuInvalidateTLB
BL armMmuDisable
;/*********************************************************************************************************
; 初始化 DATA 段
;*********************************************************************************************************/
LDR R1, =_etext ;/* -> ROM data end */
LDR R2, =_data ;/* -> data start */
LDR R3, =_edata ;/* -> end of data */
LINE_LABEL(1)
CMP R2, R3 ;/* check if data to move */
LDRLO R0, [R1], #4 ;/* copy it */
STRLO R0, [R2], #4
BLO 1b ;/* loop until done */
;/*********************************************************************************************************
; 清 0 BSS 段
;*********************************************************************************************************/
MOV R0, #0 ;/* get a zero */
LDR R1, =__bss_start ;/* -> bss start */
LDR R2, =__bss_end ;/* -> bss end */
LINE_LABEL(2)
CMP R1, R2 ;/* check if data to clear */
STRLO R0, [R1], #4 ;/* clear 4 bytes */
BLO 2b ;/* loop until done */
DSB
;/*********************************************************************************************************
; 调用 targetInit 函数
;*********************************************************************************************************/
LDR R10, =targetInit
MOV LR, PC
BX R10
;/*********************************************************************************************************
; 进入 halPrimaryCpuMain 函数 (argc = 0, argv = NULL, frame pointer = NULL)
;*********************************************************************************************************/
MOV R0, #0
MOV R1, #0
MOV R2, #0
MOV FP, #0
LDR R10, =halPrimaryCpuMain
MOV LR, PC
BX R10
B .
FUNC_END()