嵌入式Linux设备OTA入门
·
引言
为什么需要OTA?如果你的嵌入式产品量产并大卖,产品发往世界各地,当你想给产品进行软件升级的时候怎么办呢?这个时候就需要OTA(Over-the-Air)空中下载技术。那嵌入式产品往往还伴随着以下问题:
- 存储资源受限
- 网络环境恶劣,丢包率高
- 存在断电风险
- 无人工干预,需要设备100%自主完成
接下来让我们看看如何设计OTA让设备软件成功升级,而不变砖的。
一、OTA核心架构
1.1 A/B分区系统
双分区系统这是避免变砖的关键设计。假设eMMC布局如下
/dev/mmcblk0
├─p1: bootloader (U-Boot) # 引导程序
├─p2: boot_a # 内核A分区
├─p3: rootfs_a # 根文件系统A
├─p4: boot_b # 内核B分区
├─p5: rootfs_b # 根文件系统B
├─p6: ota_data # OTA元数据分区
└─p7: user_data # 用户数据分区
- 分区大小规划:每个根文件系统分区应预留20-30%的额外空间,用于存放临时文件、日志和未来版本增量
- OTA元数据分区:这个分区通常很小(4-16MB),存放OTA状态、回滚计数、升级日志等关键信息(存储空间有限的嵌入式设备可以没有此分区,并将其中部分状态写入uboot环境变量)
- 数据分区独立:user_data分区存储应用数据,避免OTA时用户数据丢失
更新时的操作:
- 如果当前运行在A分区,则将新的版本下载更新到B分区
- 验证通过后,只更新B分区的内容
- 引导程序切换到B分区启动
- 如果B分区启动失败(可设置多次判断,如3次重启失败),自动回退到A分区
在U-Boot中,需要设置启动计数器和回滚逻辑。U-Boot中的关键环境变量:
# 查看当前启动分区
fw_printenv bootpart
# 设置从B分区启动
fw_setenv bootpart 2
fw_setenv bootargs "root=/dev/mmcblk0p5 rootwait rw"
# 安全回退机制:启动计数器
fw_setenv bootcount 0
fw_setenv bootlimit 3
# 每次启动递增bootcount,如果超过bootlimit仍失败,则切换回A分区
1.2 OTA客户端
这是常驻后台的守护进程,核心职责有以下三个:
- 定期心跳,上报状态
- 检查更新
- 触发更新流程
开发要点:
- 必须轻量,内存占用通常控制在5MB以内
- 实现指数退避的重试机制,避免网络风暴
- 心跳协议要包含设备健康状态(电池、存储、信号强度)
1.3 更新引擎
这是最复杂的部分,必须处理所有异常情况。以下是简化流程:
脚本
- 准备阶段:创建文件夹
- 下载更新包(支持断点续传)
- 安全验证:验证数字签名、验证哈希值
- 应用更新
- 原子性提交:标记更新成功、标记更新失败,触发回滚
原子性的核心是:一个操作要么完全执行,要么完全不执行,不会出现"执行一半"的状态。这也是减少升级过程中出现问题的关键。
1.4 安全验证体系
嵌入式设备最怕被植入恶意固件。数字签名流程:
# 服务器端生成签名
openssl dgst -sha256 -sign private_key.pem \
-out update.bin.sig \
update.bin
# 设备端验证签名(公钥已预置在固件中)
openssl dgst -sha256 -verify /etc/ota/public_key.pem \
-signature update.bin.sig \
update.bin
实际开发中的增强措施:
-
双密钥轮转:生产密钥和恢复密钥分离
-
版本防回滚:防止攻击者用旧版本漏洞
// 版本检查逻辑
if (new_version <= current_version) {
log_warn("Version rollback attempt detected!");
return -EPERM;
}
二、开发中的挑战
断电处理:状态机+原子操作的设计,让每次状态变化都立即持久化,确保在任何时刻断电都不变砖
存储空间不足的解决方案:差分升级包,压缩升级包
健康检查机制:确保新系统能工作,比如在新版本运行到指定阶段或者指定时长后,再清除升级失败计数器
三、自研vs开源
自研方案的优势与代价
何时应该自研?
-
硬件极其特殊(MCU+外置Flash,无标准MMC)
-
更新逻辑特别简单(只更新一个应用)
-
公司已有深厚的基础设施
-
对安全有特殊合规要求
自研的隐藏成本:
-
测试成本:需要模拟各种异常(断电、断网、存储坏块)
-
维护成本:每个新硬件平台都要适配
-
生态成本:缺少社区支持,所有问题自己解决
开源工具
SWUpdate、 RAUC、Mender
更多推荐


所有评论(0)