可靠的 Bootloader 与 OTA 升级策略设计

Evek Golden Lv4

在物联网时代,无法进行远程升级(OTA)的设备是没有灵魂的。而 Bootloader 则是 OTA 的基石。如果 Bootloader 挂了,设备就只能返厂了。如何设计一个“变砖”概率为 0 的 Bootloader?

1. 启动流程全景

一个支持 OTA 的典型嵌入式存储布局如下:

1
2
3
4
5
6
7
8
9
+---------------+ 0x0800 0000 (Flash Base)
| Bootloader | (不可升级,只读保护)
+---------------+ 0x0800 4000
| Settings | (存储升级标志位、版本号等)
+---------------+ 0x0800 5000
| App (Slot A) | (当前运行的固件)
+---------------+ 0x0804 0000
| App (Slot B) | (下载的新固件 / 备份区)
+---------------+

启动逻辑

上电后,MCU 默认复位中断向量指向 Bootloader。

  1. 硬件初始化:初始化时钟、看门狗(关键!)、Flash 接口。
  2. 检查标志位:读取 Settings 区,判断是否有“待安装更新”。
  3. 校验固件:计算 Flash 内容的 CRC/SHA256,确保固件不完整不运行。
  4. 跳转:关闭所有中断,重置 MSP 指针,修改中断向量表偏移(SCB->VTOR),跳转到 App 的 Reset Handler。

2. 核心架构:Dual Bank (A/B 分区)

最稳健的 OTA 策略是 A/B 分区切换(Dual Slot)。

  • 工作原理
    • 当前运行在 Slot A。
    • 后台下载新固件到 Slot B。
    • 下载完成并校验通过后,重启。
    • Bootloader 检查到 Slot B 有有效固件,将 Slot B 设为 Active,Slot A 设为 Inactive(或者进行搬运覆盖,视 Flash 大小而定)。
  • **回滚机制 (Rollback)**:
    • 新固件启动后,必须在 N 分钟内通过“自检”(如成功连接服务器)。
    • 如果自检通过,标记“确认生效”。
    • 如果自检失败(Bug 导致看门狗复位),Bootloader 发现虽然在 Slot B 但没有“确认生效”标记,自动切回 Slot A。
    • 结论:只要 Bootloader 不坏,永远有退路。

3. 差分升级 (Differential Update)

随着固件越来越大(几 MB),4G/WiFi 流量和时间成本都很高。差分升级技术可以将升级包压缩到原来的 5% - 10%。

  • 原理:在服务器端比较 v1.0.binv1.1.bin 的二进制差异,生成 diff.patch
  • 端侧实现:Bootloader 内置一个轻量级的 Patch 算法(如 BSDiff 的嵌入式变种)。
    • 读取 Slot A 旧固件 + RAM 中的 Patch 包 -> 在 Slot B 生成新固件。
  • 挑战:需要消耗较多的 RAM 用于还原算法,且 Flash 读写次数增加。

4. 安全性设计 (Secure Boot)

如果黑客把篡改过的固件刷入你的设备,这就变成了“肉鸡”。

  1. 数字签名
    • 开发者持有私钥 (Private Key),对固件的 Hash 值签名。
    • 设备 Bootloader 中内置公钥 (Public Key)。
  2. 验签
    • Bootloader 启动或升级前,用公钥解密签名,对比计算出的 Hash。
    • 如果不一致,拒绝启动。
    • 推荐算法:ECDSA-secp256r1 (速度快,密钥短)。

5. 开发建议

  1. Bootloader 越简单越好:不要在 Bootloader 里跑 OS,不要跑复杂协议栈。逻辑越少,Bug 越少。
  2. Flash 保护:在量产时,务必锁定 Bootloader 区域的 Flash 写权限 (Write Protection)。
  3. 掉电保护:在搬运固件或写标志位时突然断电怎么办?使用原子操作或多级标志位确认,确保状态机不会卡在中间状态。
  • Title: 可靠的 Bootloader 与 OTA 升级策略设计
  • Author: Evek Golden
  • Created at : 2025-06-05 23:12:00
  • Updated at : 2026-06-12 08:57:02
  • Link: https://blog.cocodemo.uno/posts/ota5k1m/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments