am335x u-boot启动过程分析

2018/04/06 22:33
阅读数 357

  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
    
}

(待续...)

 

  

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部