针对DRA75x of TI UBOOT(2013-04) 全面解析整个流程

/**********针对DRA75x of TI UBOOT**************/
1.arch/arm/cpu/u-boot.lds(_start入口)

2.arch/arm/cpu/armv7/start.S(b _main ,cpu_init_crit b lowlevel_init)
  a.arch/arm/cpu/armv7/lowlevel_init.S (b s_init)
  b.arch/arm/cpu/armv7/omap-common/hwinit-common.c(s_init)
    /*
     * Routine: s_init
     * Description: Does early system init of watchdog, muxing,  andclocks
     * Watchdog disable is done always. For the rest what gets done
    * depends on the boot mode in which this function is executed
        *   1. s_init of SPL running from SRAM
     *   2. s_init of U-Boot running from FLASH
     *   3. s_init of U-Boot loaded to SDRAM by SPL
     *   4. s_init of U-Boot loaded to SDRAM by ROM code using the
     *      Configuration Header feature
     * Please have a look at the respective functions to see what gets
     * done in each of these cases
     * This function is called with SRAM stack.
     */
    void s_init(void)
    {
    #if defined(CONFIG_BOOTIPU1) && defined(CONFIG_SPL_BUILD)
    /*1-ms tick with 32.768-Hz functional clock generated (only TIMER1, TIMER2, and TIMER10)
        COUNTER_32K【CR】0x4AE04030
        先读取LSB(16bit) *((volatile unsigned short *)0x4AE04030)
        再读取MSB(16bit) *((volatile unsigned short *)(0x4AE04030+2))>>16
        u32 reg_val = MSB|LSB;
    */
        volatile u32 spl_time = read_fast_counter();
    
    #endif
        /*
         * 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();
    /*
     *
     */
        arm_errata_798870();
    #endif
    /*397page CTRL_WKUP_ID_CODE 0x4AE0 C204
     *Silicon Type VERSION RAMP_SYSTEM ID_CODE
     *DRA75x/DRA74x ES1.0 0x0 0xB990 0x0B99002F
     *DRA75x/DRA74x ES1.1 0x1 0xB990 0x1B99002F
     */
        init_omap_revision();
    /*
     *初始哈板子版本信息
     */
        hw_data_init();
    /*
     *
     */
        prcm_init();

      #ifdef CONFIG_SPL_BUILD
    /*
     *
     */
        if (warm_reset() && (omap_revision() <= OMAP5430_ES1_0))
                force_emif_self_refresh();
    #endif
        watchdog_init();
    /*To disable the timer, follow this sequence:
        1. Write 0xXXXX AAAA in the WSPR.
        2. Write 0xXXXX 5555 in the WSPR.    
    To enable the timer, follow this sequence:
        1. Write 0xXXXX BBBB in the WSPR.
        2. Write 0xXXXX 4444 in the WSPR.
        WWPS用来查看状态是否写完(pending)
    */
    /*
     *设置pad的寄存器,配置引脚功能
     */
        set_mux_conf_regs();
    #ifdef CONFIG_SPL_BUILD
    /*
     *
     */
        srcomp_enable();
    #endif
    #if defined(CONFIG_SPL_BUILD) || defined(CONFIG_XIP_NOR)
    /*
     *设置L4per总线时钟,并且设置uart1_module时钟
     */
        setup_clocks_for_console();
    #endif
    #ifdef CONFIG_SPL_BUILD
        gd = &gdata;
    /*
     *开始注册serial_init();
     */
        preloader_console_init();
    /*
     *
     */
        do_io_settings();
    #endif

    #ifdef CONFIG_SPL_BUILD
        /* For regular u-boot sdram_init() is called from dram_init() */
        sdram_init();
    /*
     * SDRAM initialization:
     * SDRAM initialization has two parts:
     * 1. Configuring the SDRAM device
     * 2. Update the AC timings related parameters in the EMIF module
    * (1) should be done only once and should not be done while we are
     * running from SDRAM.
     * (2) can and should be done more than once if OPP changes.
     * Particularly, this may be needed when we boot without SPL and
     * and using Configuration Header(CH). ROM code supports only at 50% OPP
     * at boot (low power boot). So u-boot has to switch to OPP100 and update
     * the frequency. So,
     * Doing (1) and (2) makes sense - first time initialization
     * Doing (2) and not (1) makes sense - OPP change (when using CH)
     * Doing (1) and not (2) doen't make sense
     * See do_sdram_init() for the details
     */

        gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
        gd->bd->bi_dram[0].size = omap_sdram_size();
    /*DMM_LISA_MAP_i addr:0x4E00 0040 + (0x4 * i) 【SYS_ADDR】【SYS_SIZE】【SDRC_ADDRSPC】
     * total_size = (sdram_end - sdram_start) - (trap_size);
     */
    #ifdef CONFIG_BOOTIPU1
        printf("Time at start of SPL: %5d ms\n", ((int)(spl_time*1000/32768.0)));
    #endif
    #endif
    #if defined(CONFIG_SPL_EARLY_BOOT) || !defined(CONFIG_SPL_BUILD)
    /*
     *IRQ_CROSSBAR DMA_CROSSBAR设定
     */
        set_crossbar_regs();
    #endif
    }

3.arch/arm/lib/crt0.S(_main b board_init_f , b board_init_r)

4.arch/arm/lib/board.c(board_init_f , board_init_r ,main_loop())

/*
    ENET Driver 加载过程
    board_init_r()
    board_init()
        eth_initialize()--->net/eth.c
                board_eth_init() / cpu_eth_init()需要实现,之后调用cpsw_register()
                        cpsw_register()---->drivers/net/cpsw.c
                                eth_register()

*/
/**********UART 动作***************/
1.set_mux_conf_regs();配置pad寄存器,指定uart功能
2.void setup_clocks_for_console(void);连接总线输出到module时钟。
{
        /*UART 在l4per总线,首先配置l4per软件唤醒,配置完Module时钟,再将l4per_clkstctrl硬件自动唤醒*/
        /* Do not add any spl_debug prints in this function */
        /*L4PER_CLKSTCTRL SW_WKUP*/
        clrsetbits_le32((*prcm)->cm_l4per_clkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK,
                        CD_CLKCTRL_CLKTRCTRL_SW_WKUP <<
                        CD_CLKCTRL_CLKTRCTRL_SHIFT);
    /*UART1_CLKCTRL*/
        /* Enable all UARTs - console will be on one of them */
        clrsetbits_le32((*prcm)->cm_l4per_uart1_clkctrl,
                        MODULE_CLKCTRL_MODULEMODE_MASK,
                        MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
                        MODULE_CLKCTRL_MODULEMODE_SHIFT);

        clrsetbits_le32((*prcm)->cm_l4per_uart2_clkctrl,
                        MODULE_CLKCTRL_MODULEMODE_MASK,
                        MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
                        MODULE_CLKCTRL_MODULEMODE_SHIFT);

        clrsetbits_le32((*prcm)->cm_l4per_uart3_clkctrl,
                        MODULE_CLKCTRL_MODULEMODE_MASK,
                        MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
                        MODULE_CLKCTRL_MODULEMODE_SHIFT);

        clrsetbits_le32((*prcm)->cm_l4per_uart4_clkctrl,
                        MODULE_CLKCTRL_MODULEMODE_MASK,
                        MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN <<
                        MODULE_CLKCTRL_MODULEMODE_SHIFT);
        /*HW_AUTO*/
        clrsetbits_le32((*prcm)->cm_l4per_clkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK,
                        CD_CLKCTRL_CLKTRCTRL_HW_AUTO <<
                        CD_CLKCTRL_CLKTRCTRL_SHIFT);
    /*clrsetbits_le32功能(清除)~(CD_CLKCTRL_CLKTRCTRL_MASK)|(写入)CD_CLKCTRL_CLKTRCTRL_HW_AUTO <<
                        CD_CLKCTRL_CLKTRCTRL_SHIFT*/
}       
3.void preloader_console_init(void);Uart初始化波特率调用 serial_init()进行驱动注册。
{
        gd->bd = &bdata;
        gd->baudrate = CONFIG_BAUDRATE;

        serial_init();          /* serial communications setup */--->    drivers/serial/serial.c

        gd->have_console = 1;

        puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \
                        U_BOOT_TIME ")\n");
#ifdef CONFIG_SPL_DISPLAY_PRINT
        spl_display_print();//读出板子信息例如DRA754x-ES1.0,并且打印出来
#endif
}
4.完成驱动函数实现
 .start  = Console uart寄存器初始化,设置通信方式115200 8n1 hwflow,波特率设置等
 .stop   =           停止工作
 .setbrg =  改变波特率设置
 .putc   =  输出字符
 .puts   =  输出字符串
 .getc   =  获取字符
 .tstc   =  测试接受fifo是否为空。
/**********UART 动作***************/

你可能感兴趣的:(U-BOOT)