第二阶段主要完成板级初始化、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






