U-Boot 启动速度与可靠性优化
产品启动速度很重要,但优化启动速度不能以牺牲可靠性和可排障性为代价。你应该先建立可测量的启动基线,再逐项优化。
启动优化最怕“凭感觉”。你看到一大段日志,直觉认为串口输出慢;但真正耗时可能在 DHCP、存储扫描、DRAM training、USB 初始化或 Linux rootfs 检查。先测量,再优化。
1. 先测量
保存完整串口日志,并标记时间点:
- 上电到第一行固件输出。
- SPL 阶段耗时。
- U-Boot proper 初始化耗时。
- 自动启动等待时间 。
- 加载 kernel/DTB/rootfs 耗时。
- Linux kernel 到用户空间耗时。
没有测量,就不要猜测瓶颈。
可以建立一张表:
| 阶段 | 开始时间 | 结束时间 | 耗时 | 备注 |
|---|---|---|---|---|
| Boot ROM/SPL | ||||
| U-Boot proper | ||||
| bootdelay | ||||
| 加载 kernel/DTB | ||||
| Linux kernel | ||||
| 用户空间 |
如果串口日志没有时间戳,可以使用外部串口工具记录时间,或者让 Linux 打印 printk.time=1。更精细的测量可能需要 GPIO 翻转、示波器或逻辑分析仪。
2. U-Boot 阶段常见耗时来源
- 等待自动启动倒计时。
- 扫描不存在的启动设备。
- DHCP 或网络超时。
- USB 初始化和枚举。
- 慢速存储读取。
- 过多调试日志。
- 设备 probe 失败后等待超时。
- 固件验证和 hash 计算。
先定位是哪一项,再决定是否优化。
3. 常见优化方向
- 缩短或取消
bootdelay,但保留恢复入口。 - 关闭不必要命令和驱动,减小镜像体积。
- 减少启动扫描设备数量。
- 固定启动介质,避免全盘扫描。
- 使用更快的存储或加载方式。
- 优化 DTB 和驱动 probe。
- 减少串口日志,但保留故障模式日志。
例如,开发阶段 boot_targets 可能包含 mmc usb pxe dhcp,产品中如果只从 eMMC 启动,就可以固定启动目标,避免每次扫描 USB 和网络。
4. bootdelay 怎么优化
bootdelay 是最直接的耗时项:
# [U-Boot]
printenv bootdelay
把 3 秒改成 1 秒,立刻节省 2 秒。但如果完全取消中断启动,你可能失去现场救援入口。产品中常见折中:
- 默认短 bootdelay。
- 特定按键进入 recovery。
- 连续启动失败后自动进入 recovery。
- 工厂模式保 留较长等待。
不要为了速度把所有人工入口都删掉。
5. 镜像体积与加载速度
减小 U-Boot 或 kernel 体积可能缩短加载时间,但影响取决于介质速度。SPI NOR、慢速 NAND、网络 TFTP 下效果更明显;高速 eMMC/NVMe 下可能不是主要瓶颈。
优化前先测量加载耗时。不要为了减小几十 KB 删除关键调试命令,导致现场无法排障。
6. 可靠性优先
为了快几百毫秒而删除恢复路径,通常得不偿失。产品至少应保留:
- 中断启动或 recovery 触发方式。
- watchdog 策略。
- 启动失败回滚。
- 关键日志。
- 可识别的版本信息。
可靠性优化也包括:
- 启动失败自动回滚。
- watchdog 配置合理。
- 存储读取失败有重试。
- 启动状态可记录。
- 关键镜像可校验。
7. 常见误区
看到启动日志多,不等于日志就是主要耗时。看到 U-Boot 阶段长,也可能是存储读慢、网络 DHCP 慢或设备扫描超时。优化前要先定位时间花在哪里。
只优化 U-Boot,不看 Linux
很多产品启动慢,主要耗时在 Linux kernel 或用户空间。U-Boot 只占其中一小段。需要从上电到业务可用全链路测量。
删除所有日志
日志少了不等于启动快很多。删除关键日志会让现场问题更难排查。更好的做法是区分正常模式和调试模式。
只测一次
启动时间会受缓存、网络、存储状态、电源和外设影响。至少多测几次,记录平均值和最坏值。
8. 优化流程
建议按下面流程:
- 保存基线日志。
- 标记各阶段耗时。
- 找最大耗时项。
- 只改一个变量。
- 复测并记录。
- 确认 recovery 和回滚仍然可用。
- 再进入下一项优化。
本章小结
启动优化的顺 序是:测量、定位、修改、复测。不要凭感觉删功能。真正好的产品启动链,是快、稳、可恢复三者之间的平衡。
思考与练习
- 保存一份完整启动日志,并标出 U-Boot 阶段耗时。
- 找出你的启动链中最大的等待项。
- 说明为什么不能为了缩短
bootdelay而删除所有 recovery 入口。