从start.S跳转到crt0.S的_main函数
crt0.S主要做了
1.重新设置sp堆栈
2.GD区域清零
3.跳转到board_init_f(); //gd初始化/ ddr初始化/ 搬运
4.将镜像从硬件介质(flash等)搬运到外部ddr,将GD从内部的SRAM搬运至外部ddr。
5.清除bss段。
5.完整C语言环境建立完毕。
6.跳转到外部ddr中执行代码board_init_r()完成后续工作。
这里直接使用伪c语言代码进行注释。
ENTRY(_main)
/*
* Set up initial C runtime environment and call board_init_f(0).
*/
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
ldr sp, =(CONFIG_SPL_STACK) //sp = CONFIG_SPL_STACK 重新设置堆栈
#else
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) //sp = CONFIG_SYS_INIT_SP_ADDR
#endif
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ //sp = sp & ~(0x7)
mov r2, sp //r2 = sp
sub sp, sp, #GD_SIZE /* allocate one GD above SP */ //sp = sp - GD_SIZE
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ //sp = sp & ~(0x7)
mov r9, sp /* GD is above SP */ //r9 = sp
mov r1, sp //r1 = sp
mov r0, #0 //r0 = 0
clr_gd:
cmp r1, r2 /* while not at end of GD */ //while(r1 < r2) { //GD区域清零
strlo r0, [r1] /* clear 32-bit GD word */ // *r1 = r0 = 0
addlo r1, r1, #4 /* move to next */ // r1 = r1 + 4
blo clr_gd //}
#if defined(CONFIG_SYS_MALLOC_F_LEN)
sub sp, sp, #CONFIG_SYS_MALLOC_F_LEN //sp = sp - CONFIG_SYS_MALLOC_F_LEN
str sp, [r9, #GD_MALLOC_BASE] //*(r9+GD_MALLOC_BASE) = sp
#endif
/* mov r0, #0 not needed due to above code */
bl board_init_f //board_init_f(); //gd初始化/ ddr初始化/ 搬运
#if ! defined(CONFIG_SPL_BUILD)
/*
* Set up intermediate environment (new sp and gd) and call
* relocate_code(addr_moni). Trick here is that we'll return
* 'here' but relocated.
*/
ldr sp, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */ // sp = *(r9+GD_START_ADDR_SP)
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ // sp = sp & ~(0x07)
ldr r9, [r9, #GD_BD] /* r9 = gd->bd */ // r9 = *(r9+GD_BD)
sub r9, r9, #GD_SIZE /* new GD is below bd */ // r9 = r9 - GD_SIZE
adr lr, here // lr = here:
ldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */ // r0 = *(r9+GD_RELOC_OFF)
add lr, lr, r0 // lr = lr + r0
ldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */ // r0 = *(r9+GD_RELOCADDR)
b relocate_code // relocate_code(); //将镜像从flash中搬至r0地址处
here: // here = gd->reloc_off + lr
/*
* now relocate vectors
*/
bl relocate_vectors //relocate_vectors(); //将vectors搬至gd->relocaddr
/* Set up final (full) environment */
bl c_runtime_cpu_setup /* we still call old routine here */ //c_runtime_cpu_setup(); //I-cache is enabled invalidate it
#endif
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)
# ifdef CONFIG_SPL_BUILD
/* Use a DRAM stack for the rest of SPL, if requested */
bl spl_relocate_stack_gd //spl_relocate_stack_gd(); //gd搬家
cmp r0, #0 //if(r0 != 0)
movne sp, r0 //sp = r0
# endif
ldr r0, =__bss_start /* this is auto-relocated! */ //r0 = __bss_start
#ifdef CONFIG_USE_ARCH_MEMSET
ldr r3, =__bss_end /* this is auto-relocated! */ //r3 = __bss_end
mov r1, #0x00000000 /* prepare zero to clear BSS */ //r1 = 0x00000000
subs r2, r3, r0 /* r2 = memset len */ //r2 = r3 - r0
bl memset //memset();
#else
ldr r1, =__bss_end /* this is auto-relocated! */ //r1 = __bss_end
mov r2, #0x00000000 /* prepare zero to clear BSS */ //r2 = 0x00000000
clbss_l:cmp r0, r1 /* while not at end of BSS */ //while(r0 < r1){
strlo r2, [r0] /* clear 32-bit BSS word */ //*r0 = r2
addlo r0, r0, #4 /* move to next */ // r0 = r0 + 4
blo clbss_l //}
#endif
#if ! defined(CONFIG_SPL_BUILD)
bl coloured_LED_init //coloured_LED_init();
bl red_led_on //red_led_on
#endif
/* call board_init_r(gd_t *id, ulong dest_addr) */
mov r0, r9 /* gd_t */ // r0 = r9
ldr r1, [r9, #GD_RELOCADDR] /* dest_addr */ // r1 = *(r9 + GD_RELOCADDR)
/* call board_init_r */
ldr pc, =board_init_r /* this is auto-relocated! */ // pc = board_init_r
/* we should not return here. */
#endif
ENDPROC(_main)