banner
NEWS LETTER

嵌入式 Linux 系列 09:OTA 升级、双分区和失败回滚

Scroll down

设备能在实验室跑起来,只是第一步。真正部署到现场后,固件升级能力会变得非常关键。没有可靠 OTA,后续修 bug、加功能、修安全问题都会变成高风险操作。

一、OTA 要解决什么

OTA 不是简单下载一个文件然后覆盖系统。它至少要解决:

  • 下载完整性。
  • 版本校验。
  • 断点或失败处理。
  • 写入过程断电保护。
  • 升级后启动验证。
  • 失败回滚。
  • 保留用户配置。

现场设备最怕升级后变砖,所以 OTA 设计的核心目标是:失败可以回到旧版本。

二、常见分区方案

简单方案:

1
2
3
boot
rootfs
data

风险是升级 rootfs 时如果断电,系统可能无法启动。

更稳的方案是 A/B 双分区:

1
2
3
4
boot
rootfs_a
rootfs_b
data

当前从 A 启动时,升级写入 B。写完后修改启动标记,下次从 B 启动。如果 B 启动失败,再回滚到 A。

三、升级状态机

可以定义几个状态:

1
2
3
4
5
6
7
8
9
idle
downloading
verified
writing
pending_reboot
testing
committed
rollback
failed

升级状态要写入可持久化分区,例如:

1
/data/ota/state.json

不要只存在内存里。断电重启后,设备必须知道升级进行到哪一步。

四、镜像校验

下载后至少校验 sha256:

1
sha256sum firmware.bin

更完整的做法是:

  • 固件包带 manifest。
  • manifest 包含版本、目标型号、文件大小、sha256。
  • manifest 用私钥签名。
  • 设备用内置公钥验签。

这样可以避免下载损坏或被替换的固件。

五、启动确认和回滚

升级后第一次启动不能立刻认为成功。可以设置 pending 标记:

1
2
3
boot_slot=B
upgrade_state=testing
boot_count=0

业务服务启动成功、网络连接成功、核心功能自检通过后,再执行 commit:

1
upgrade_state=committed

如果连续几次启动都没有 commit,Bootloader 或早期启动脚本应该回滚到旧分区。

六、data 分区要保留

OTA 通常不应该清空用户配置:

1
2
3
/data/config
/data/log
/data/ota

但版本升级可能带来配置格式变化,所以应用要支持配置迁移:

1
config_version: 1 -> 2

迁移失败要有默认值和日志,不要让服务直接崩溃。

七、最小验收清单

OTA 至少要测:

  • 正常升级。
  • 下载中断。
  • 写入中断。
  • 校验失败。
  • 升级后应用启动失败。
  • 回滚后旧版本可用。
  • 用户配置仍然存在。

OTA 做到最后,拼的是异常路径。正常路径跑通不代表能上现场。

其他文章
目录导航 置顶
  1. 1. 一、OTA 要解决什么
  2. 2. 二、常见分区方案
  3. 3. 三、升级状态机
  4. 4. 四、镜像校验
  5. 5. 五、启动确认和回滚
  6. 6. 六、data 分区要保留
  7. 7. 七、最小验收清单
请输入关键词进行搜索