Linux BSP实战课(SoC bringup篇):Uboot的初始化过程

2023-11-13 15:48:38 浏览数 (1)

  • Uboot 启动
  • 驱动
  • 交互
    • booti
  • Kernel 启动

Uboot 启动

board_init_r 是执行 Uboot 的关键函数,该函数定义在 common/board_r.c 中,主要作用是进行一些必要的初始化工作,然后根据相关的配置情况,读取 Uboot,并启动它。

代码语言:javascript复制
void board_init_r(gd_t *new_gd, ulong dest_addr)
{
......
#ifdef CONFIG_NEEDS_MANUAL_RELOC
        int i;
#endif
......
        gd->flags &= ~GD_FLG_LOG_READY;

#ifdef CONFIG_NEEDS_MANUAL_RELOC
        for (i = 0; i < ARRAY_SIZE(init_sequence_r); i  )
                init_sequence_r[i]  = gd->reloc_off;
#endif

        if (initcall_run_list(init_sequence_r))
                hang();

        /* NOTREACHED - run_main_loop() does not return */
        hang();
}

nit_sequence_r 中存储着一系列的初始化函数,initcall_run_list 确保了各系统初始化的顺序运行。根据 CONFIG_XX 来使能相应的驱动,最后 run_main_loop 进入循环。如下所示:

代码语言:javascript复制
static init_fnc_t init_sequence_r[] = {
        ......
        initr_barrier,
        //初始化gd中与malloc相关的成员
        initr_malloc,
        //log初始化
        log_init,
        initr_bootstage,        /* Needs malloc() but has its own timer */
        ......
#ifdef CONFIG_DM
        //初始化驱动模型相关
        initr_dm,
#endif
#ifdef CONFIG_ADDR_MAP
        initr_addr_map,
#endif
#if defined(CONFIG_ARM) || defined(CONFIG_NDS32) || defined(CONFIG_RISCV) || 
        defined(CONFIG_SANDBOX)
        //板子初始化
        board_init,     /* Setup chipselects */
#endif
        ......
        initr_dm_devices,
        stdio_init_tables,
        //串口初始化
        serial_initialize,
        initr_announce,
#if CONFIG_IS_ENABLED(WDT)
        //看门狗初始化
        initr_watchdog,
#endif
        ......
        //上电
        power_init_board,
        ......
#ifdef CONFIG_MMC
        //mmc初始化
        initr_mmc,
#endif
        ......
        //串口
        console_init_r,         /* fully init console as a device */
#ifdef CONFIG_DISPLAY_BOARDINFO_LATE
        console_announce_r,
        //打印版子信息
        show_board_info,
#endif
        ......
        interrupt_init,
#if defined(CONFIG_MICROBLAZE) || defined(CONFIG_M68K)
        //定时器
        timer_init,             /* initialize timer */
#endif
#if defined(CONFIG_LED_STATUS)
        //led
        initr_status_led,
#endif
        /* PPC has a udelay(20) here dating from 2002. Why? */
#ifdef CONFIG_CMD_NET
        //网络
        initr_ethaddr,
#endif
        ......
        run_main_loop,
};

驱动

从上面的代码可以知道 init_sequence_r 会根据宏定义初始化相应的功能,这里列出主要的几个,如下所示:

这里我们重点关注 mmc 和 net 驱动的初始化。

0 人点赞