跳到主要内容

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. 优化流程

建议按下面流程:

  1. 保存基线日志。
  2. 标记各阶段耗时。
  3. 找最大耗时项。
  4. 只改一个变量。
  5. 复测并记录。
  6. 确认 recovery 和回滚仍然可用。
  7. 再进入下一项优化。

本章小结

启动优化的顺序是:测量、定位、修改、复测。不要凭感觉删功能。真正好的产品启动链,是快、稳、可恢复三者之间的平衡。

思考与练习

  1. 保存一份完整启动日志,并标出 U-Boot 阶段耗时。
  2. 找出你的启动链中最大的等待项。
  3. 说明为什么不能为了缩短 bootdelay 而删除所有 recovery 入口。