am335x u-boot啟動過程分析


  u-boot屬於兩階段的bootloader,第一階段的文件為 arch/arm/cpu/armv7/start.S 和 arch/arm/cpu/armv7/lowlevel_init.S,前者是平台相關的,后者是開發板相關的。

1. u-boot第一階段代碼分析

  (1)硬件設備初始化

   將CPU的工作模式設為管理模式(SVC);

  關閉中斷;

  禁用MMU,TLB ;

  板級初始化;

  (2)為加載Bootloader的第二階段代碼准備RAM空間

  加載u-boot.img,跳轉到u-boot.img;

  上述工作,也就是uboot-spl代碼流程的核心。

 

代碼如下: 
arch/arm/cpu/armv7/start.S

 1 /*
 2  * the actual reset code
 3  */
 4 reset:
 5     bl    save_boot_params
 6     /*
 7      * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
 8      * except if in HYP mode already
 9      */
10     mrs    r0, cpsr
11     and    r1, r0, #0x1f        @ mask mode bits
12     teq    r1, #0x1a        @ test for HYP mode
13     bicne    r0, r0, #0x1f        @ clear all mode bits
14     orrne    r0, r0, #0x13        @ set SVC mode
15     orr    r0, r0, #0xc0        @ disable FIQ and IRQ
16     msr    cpsr,r0
17 @@ 以上通過設置CPSR寄存器里設置CPU為SVC模式,禁止中斷
18 @@ 具體操作可以參考《[kernel 啟動流程] (第二章)第一階段之——設置SVC、關閉中斷》的分析
19 
20     /* the mask ROM code should have PLL and others stable */
21 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
22     bl    cpu_init_cp15
23 @@ 調用cpu_init_cp15,初始化協處理器CP15,從而禁用MMU和TLB。
24 @@ 具體操作可以參考[kernel 啟動流程] (第六章)第一階段之——打開MMU兩篇文章的分析
25     bl    cpu_init_crit
26 @@ 調用cpu_init_crit,進行一些關鍵的初始化動作,也就是板級的初始化
27 @@ 后面會有一小節進行分析
28 #endif
29 
30     bl    _main
31 @@ 跳轉到主函數,也就是要加載BL2以及跳轉到BL2的主體部分
32 /*------------------------------------------------------------------------------*/

cpu_init_crit

cpu_init_crit,進行一些關鍵的初始化動作,也就是平台級和板級的初始化。其代碼核心就是lowlevel_init,如下 
arch/arm/cpu/armv7/start.S

1 ENTRY(cpu_init_crit)
2     /*
3      * Jump to board specific initialization...
4      * The Mask ROM will have already initialized
5      * basic memory. Go here to bump up clock rate and handle
6      * wake up conditions.
7      */
8     b    lowlevel_init        @ go setup pll,mux,memory
9 ENDPROC(cpu_init_crit)

所以說lowlevel_init就是這個函數的核心。 

arch/arm/cpu/armv7/lowlevel_init.S

 1 ENTRY(lowlevel_init)
 2     /*
 3      * Setup a temporary stack
 4      */
 5     ldr    sp, =CONFIG_SYS_INIT_SP_ADDR
 6     bic    sp, sp, #7 /* 8-byte alignment for ABI compliance */
 7 #ifdef CONFIG_SPL_BUILD
 8     ldr    r9, =gdata
 9 #else
10     sub    sp, sp, #GD_SIZE
11     bic    sp, sp, #7
12     mov    r9, sp
13 #endif
14     /*
15      * Save the old lr(passed in ip) and the current lr to stack
16      */
17     push    {ip, lr}
18 @@設置好棧,為接下來的C環境做好准備
19     /*
20      * go setup pll, mux, memory
21      */
22     bl    s_init
23     pop    {ip, pc}
24 ENDPROC(lowlevel_init)

以Am335x為例,在移植過程中,就需要在lowlevel_init.S里加入一些簡單的板級初始化,例如在lowlevle_init.s------->s_init中:

arch/arm/cpu/armv7/am33xx/board.c

void s_init(void)
{
    ....  
    /*
     * Save the boot parameters passed from romcode.
     * We cannot delay the saving further than this,
     * to prevent overwrites.
     */
#ifdef CONFIG_SPL_BUILD
    save_omap_boot_params();
@@
#endif
#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_NOR_BOOT)
    watchdog_disable();    //arch/arm/cpu/armv7/am33xx/board.c
    timer_init();
    set_uart_mux_conf();    // board/ti/am335x/board.c
    setup_clocks_for_console();    // arch/arm/cpu/armv7/am335x/Clock_am33xx.c
    uart_soft_reset();    // arch/arm/cpu/armv7/am33xx/board.c
#endif
       ....
    gd = &gdata;
    preloader_console_init();
@@
       ....
#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_NOR_BOOT)
    prcm_init();
    set_mux_conf_regs();
#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC)
    /* Enable RTC32K clock */
    rtc32k_enable();
#endif
    sdram_init();
#endif
    
}

(待續...)

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM