Uboot 2015 代码解析4 crt0.S

简介

从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)

猜你喜欢

转载自blog.csdn.net/a827143452/article/details/89413529
今日推荐