第二阶段主要完成板级初始化、emmc初始化、控制台初始化、中断初始化及网络初始化等,流程图如下所示:

board_init_r
核心工作是遍历执行函数指针数组init_sequence_r[]所指向的每一个函数。
initr_reloc- 标记重定位成功,malloc初始化;
initr_caches- 首先检查 I-cache 的使能状态,如果未使能 I-cache 则将其使能,接着使能 D-cache;
initr_reloc_global_data- 设置monitor_flash_len及gd成员env_addr,将EFI runtime重新定位到gd->relocadd;
initr_malloc- 分配malloc内存空间并将其初始化,malloc区域位域u-boot区的下方;
log_init- 分配log驱动空间,设置gd->flags中的log就绪标志;
initr_bootstage- 标记引导阶段;
initr_console_record- 空;
bootstage_relocate- 完整的bootstage实现,重定位当前的bootstage记录;
initr_dm- 初始化设备驱动模型,驱动模型绑定->ofdata_to_platdata(可选)->probe
初始化一个树形的驱动模型结构,在内存中也就形成了一个至少深度为2的树形结构(假设有子节点),其中gd->dm_root 保存着根节点的信息。
probe流程,先调用一下drv->ofdata_to_platdata(dev), 再去执行 probe。
board_init- 设置启动参数的地址
initr_serial- 完成串口相关初始化,但函数并未初始化实际硬件,而是向u-boot注册一下struct serial_device类型的串口设备,并将终端使用串口设备指针分配给serial_current;
initr_announce- 打印调试信息的代码,表示RAM正在运行,且u-boot已经完成了重定位;
initr_nand- 初始化nand;
initr_mmc- 初始化emmc;
initr_env- 检查早期在u-boot中的环境变量是否OK,OK就加载,否则使用默认的环境变量;
initr_secondary_cpu- 空;
stdio_add_devices- 添加标准输入输出设备;
initr_jumptable- 函数调用了jumptable_init函数以初始化跳转表,为跳转表分配内存空间,它是基于动态分配的内存空间;
console_init_r- 获取”stdin”、”stdout”及”stderr”(标准输入、标准输出及标准错误)对应的设备名字,设置串口的引脚复用功能,并打印当前的标准输入、输出、错误对应的设备名字,设置环境变量;
interrupt_init- 中断初始化,为中断设置栈;
initr_enable_interrupts- 使能中断异常;
initr_ethaddr- 从环境变量中获得并初始化网络ethaddr地址,并存到gd->bd->bi_enetaddr;
board_late_init- 复位看门狗;
initr_net- 初始化网卡;
run_main_loop







