3. R-Car启动流程验证
R-Car的启动不是“上电即跑Linux”这么简单,而是一条由多级固件逐段交接的信任链与执行链。验证启动流程,核心是回答三个问题:每一级是否被正确加载并校验、控制权是否按预期交接、时间是否落在项目预算内。下面按启动阶段展开,并给出可落地的测量与定位方法。
一、启动阶段与信任链
R-Car上电后,片内BootROM首先执行。它根据启动模式引脚(如QSPI、eMMC、SD、SCIF下载等)选择启动介质,从固定偏移读取初始引导程序。若启用安全启动,BootROM会验证第一级引导的签名与哈希,验证通过才跳转;失败则进入下载模式或停止。随后进入BL2(Trusted Firmware-A的BL2阶段),它负责初始化DDR、加载并验证BL31(EL3运行时)、BL33(通常是U-Boot)以及OP-TEE等镜像。BL31常驻EL3,提供PSCI电源管理服务;BL33即U-Boot,负责加载内核、设备树与根文件系统,最后跳转内核。内核启动后完成驱动探测、挂载rootfs并进入用户空间。
这条链的关键在于:每一级的输入(镜像、证书、密钥)和输出(下一级入口地址、参数)都必须可观测。验证时不能只看“最后进了系统”,而要确认中间每一跳都按预期发生。
二、启动时间测量方法
启动时间测量必须定义明确的起止点。常用定义:从上电复位到内核init进程启动,或到用户空间关键服务就绪。测量手段有三类:
- 硬件辅助:用GPIO在BootROM入口拉高、在init启动时拉低,示波器或逻辑分析仪直接测脉冲宽度,精度最高,适合量产一致性验证。
- 串口时间戳:在U-Boot和内核命令行启用earlycon与printk时间戳,记录各级日志的相对时间。需注意串口波特率造成的输出延迟。
- 内核内建:使用
initcall_debug或bootgraph分析各驱动初始化耗时,定位内核阶段瓶颈。
示例:某项目要求上电到init≤2.0s。实测BootROM+BL2约320ms,BL31约40ms,U-Boot约480ms,内核到init约900ms,合计约1.74s,满足要求。若U-Boot阶段因网络探测或USB枚举多耗300ms,则需裁剪bootcmd或关闭无关驱动。以上数值为教学示例,实际以项目测量为准。
三、启动失败常见原因与定位入口
启动失败按阶段划分,定位入口也随阶段不同:
| 失败阶段 | 典型现象 | 常见原因 | 定位入口 |
|---|---|---|---|
| BootROM | 串口无任何输出 | 启动模式引脚错误、介质未烧录、供电/时钟异常 | 检查模式引脚电平、确认镜像烧录偏移、测量晶振与电源 |
| 安全启动校验 | 输出校验失败后停止或进入下载模式 | 签名不匹配、密钥未烧录、镜像被篡改、证书链错误 | 查看BootROM错误码、核对密钥哈希与签名工具版本 |
| BL2/BL31 | DDR初始化失败、卡在BL2 | DDR参数不匹配、镜像加载地址冲突、TF-A日志等级过低 | 提高TF-A日志等级、检查DDR训练日志、核对镜像布局 |
| U-Boot | 能进U-Boot但无法加载内核 | bootargs错误、内核地址/DTB不匹配、存储介质读取失败 | 在U-Boot中手动执行load与bootm、检查环境变量 |
| 内核 | 内核panic或卡在挂载rootfs | rootfs路径错误、驱动缺失、设备树不匹配、init未找到 | 启用earlycon、检查root=参数、确认DTB与板级匹配 |
四、验证清单与实操建议
建议在项目早期建立启动验证清单,至少覆盖:启动模式引脚定义与实测、各级镜像的烧录偏移与校验值、安全启动密钥与签名流程、TF-A日志等级配置、U-Boot环境变量备份、内核命令行与DTB匹配关系、启动时间基线。每次修改BL2、BL31、U-Boot或DTB后,重新测量启动时间并对比基线,偏差超过10%即需排查。
实操中,可先在U-Boot命令行手动分步加载内核与DTB,确认镜像可读、地址正确,再写回bootcmd自动执行。这样能把“加载失败”与“内核自身失败”分开定位,显著缩短排障时间。
# U-Boot 手动分步验证示例(地址为教学示例)
mmc dev 0
fatload mmc 0:1 0x48080000 Image
fatload mmc 0:1 0x48000000 r8a779a0-ulcb.dtb
setenv bootargs 'console=ttySC0,115200 root=/dev/mmcblk0p2 rw rootwait'
booti 0x48080000 - 0x48000000
启动流程验证的最终目标,是让每一级交接都有日志、有校验、有时间戳,失败时能在一分钟内判断问题属于哪一级。做到这一点,后续的复杂故障定位才有稳定基线可依。