OpenHarmony启动时U-Boot在忙啥?图解从BootRom到内核加载的全过程与源码目录解析

张开发
2026/4/16 21:22:17 15 分钟阅读

分享文章

OpenHarmony启动时U-Boot在忙啥?图解从BootRom到内核加载的全过程与源码目录解析
OpenHarmony启动全流程解密从BootRom到内核加载的U-Boot源码全景指南当按下开发板的电源键时OpenHarmony系统究竟经历了怎样的奇幻旅程那些隐藏在U-Boot源码目录中的神秘文件又是如何在启动过程中各司其职的本文将带你穿越BootRom、MiniLoader、U-Boot SPL、U-Boot到Linux内核的完整启动链条同时揭示每个阶段对应的源码实现位置为开发者构建启动流程-代码实现的双重视角。1. 启动流程全景图与源码映射嵌入式系统的启动过程就像一场精心编排的交响乐每个组件都需要在精确的时刻奏响自己的音符。OpenHarmony基于Rockchip平台的典型启动序列如下BootRom → MiniLoader(TPLSPL) → U-Boot Proper → Linux Kernel → OpenHarmony1.1 BootRom阶段芯片的第一次心跳当电源接通瞬间CPU的复位向量指向芯片内部ROM中的固化代码——这就是BootRom的起点。这个阶段主要完成硬件基础初始化时钟、基本电源管理、存储控制器启动介质探测按照预设顺序扫描SPI NOR/NAND、eMMC、SD等存储设备加载MiniLoader从存储介质读取ID Block并验证签名对应源码位置rkbin/rk35/rk3568_bl31_v1.34.elf # Rockchip提供的BootRom配套固件关键点在于BootRom会验证下一阶段加载程序的数字签名这种安全启动链Chain of Trust设计可防止恶意代码注入。1.2 MiniLoader阶段TPL与SPL的双人舞MiniLoader通常由两部分组成TPL (Tiny Program Loader)运行在芯片内部SRAM中SPL (Secondary Program Loader)加载到DDR内存执行它们的主要职责包括初始化DDR控制器没有DDR系统寸步难行设置更复杂的时钟树加载完整版U-Boot到内存在U-Boot源码中这部分逻辑分散在arch/arm/mach-rockchip/rk3568/ # 芯片特定初始化 spl/ # SPL专用代码一个典型的启动时间线可能如下表所示阶段执行位置耗时(ms)关键动作BootRom芯片ROM50加载TPLTPL内部SRAM100初始化DDRSPLDDR内存150加载U-BootU-BootDDR内存500加载内核2. U-Boot源码目录深度解析U-Boot的源码结构看似复杂实则遵循清晰的模块化设计。让我们解剖关键目录与其在启动过程中的角色2.1 架构相关核心代码arch/这是系统启动后最先执行的代码区域以ARMv8架构为例arch/arm/cpu/armv8/start.S # 入口点设置异常向量、初始化MMU启动时CPU会依次执行复位向量 →_start标签设置SVC模式、禁用中断初始化关键寄存器跳转到lowlevel_init进行板级初始化2.2 板级支持包board/每个开发板在此目录有自己的配置例如board/rockchip/evb_rk3568/ # RK3568评估板特定代码 ├── Kconfig # 板级配置选项 ├── evb_rk3568.c # 板级初始化函数 └── Makefile这里实现了特定开发板的GPIO初始化外设时钟配置存储设备接口设置2.3 设备驱动中枢drivers/U-Boot支持丰富的硬件驱动结构如下drivers/ ├── clk/ # 时钟驱动 ├── mmc/ # 存储设备驱动 ├── net/ # 网络驱动 └── serial/ # 串口驱动调试必备启动过程中串口驱动会最早被初始化这就是为什么我们能在控制台看到最早的输出信息。3. 镜像构建与启动文件解析编译U-Boot会生成多个关键镜像文件它们各司其职3.1 镜像文件三剑客idbloader.img组成TPL SPL二进制作用初始化DDR并加载u-boot.imgu-boot.img完整U-Boot镜像包含设备树、环境变量等uboot.itbFIT格式镜像Flattened Image Tree可包含多个内核、设备树等生成这些镜像的编译命令链# 典型Rockchip平台编译流程 ./make.sh rk3568 # 生成idbloader.img、u-boot.img tools/mkimage -f fit-image.its uboot.itb # 生成FIT镜像3.2 启动参数传递机制U-Boot通过特定数据结构向内核传递参数主要方式包括传统ATAGSARM架构传统参数传递方式现代设备树DTB当前主流方式设备树编译流程# 从dts源文件生成dtb dtc -I dts -O dtb -o rk3568-evb.dtb arch/arm/dts/rk3568-evb.dts在U-Boot中加载设备树的典型命令# 从MMC加载设备树到内存 load mmc 0:1 ${fdt_addr_r} /boot/rk3568-evb.dtb # 启动内核时传递设备树地址 bootm ${kernel_addr_r} - ${fdt_addr_r}4. 调试技巧与实战经验4.1 启动故障排查三板斧串口日志分析确保串口波特率正确通常115200观察启动卡在哪个阶段关键节点检查# U-Boot环境下查看关键信息 bdinfo # 查看板级信息 mmc info # 检查存储设备 dm tree # 查看设备模型内存内容检查md ${kernel_addr_r} 0x100 # 查看内核镜像头 md ${fdt_addr_r} 0x100 # 检查设备树4.2 性能优化实践通过调整以下参数可显著缩短启动时间SPL优化// 在spl/Kconfig中关闭非必要功能 config SPL_DM_SERIAL bool Enable Driver Model for serial drivers in SPL default n # 在SPL中禁用复杂的驱动模型U-Boot裁剪# 通过menuconfig精简功能 make menuconfig → Boot options → 禁用不必要的命令 → Device Tree Control → 减小设备树大小启动时间优化前后对比RK3568平台实测优化项原始时间(ms)优化后(ms)SPL初始化320220U-Boot启动680450内核加载4203805. 高级主题安全启动实现现代嵌入式系统越来越重视启动安全OpenHarmony通过以下机制构建信任链硬件级信任根BootRom验证TPL签名TPL验证SPL签名U-Boot验证内核# 启用验签功能 CONFIG_FIT_SIGNATUREy CONFIG_RSA_VERIFYy安全环境变量# 设置安全相关变量 setenv bootargs dm_verity.enforce1 saveenv实现安全启动需要在编译时准备密钥# 生成RSA密钥对 openssl genrsa -out keys/dev.key 2048 openssl req -batch -new -x509 -key keys/dev.key -out keys/dev.crt # 编译时指定密钥 ./tools/mkimage -k keys -r -f fit-image.its uboot.itb在实际项目中我们曾遇到SPL验签失败导致系统无法启动的情况最终发现是Flash分区偏移配置错误导致签名信息读取异常。这类问题通常需要通过JTAG调试器捕获早期启动日志才能准确定位。

更多文章