Linux 的OTA升级学习1:Linux OTA升级方案_SWupdate
嵌入式 Linux 系统通常基于 Linux 内核进行定制和优化,包括引导程序(Bootloader)、内核、文件系统和应用程序等多个层次。这种分层架构使得 OTA 升级需要同时考虑多个组件的更新和兼容性。
Linux OTA升级方案:
核心组件: SWUpdate + U-Boot 引导程序+ 升级包生成工具 + 固件镜像 + lua脚本语言 +存储分区+校验机制 + 远程下载 + 协议
一、核心组件
1. SWUpdate 工具链功能:负责升级包解析、签名验证、分区写入及状态管理。
依赖:
LibCurl:支持 HTTP/HTTPS 远程下载升级包。
OpenSSL/mbedTLS:用于签名验证(RSA/ECDSA)和固件加密(AES)。
LZO/LZMA:可选压缩算法,减少升级包体积。2. 升级包生成工具
mkupdate:将固件镜像(如内核、根文件系统)和描述文件打包为 .swu 格式。
示例命令:bash
mkupdate -p ./firmware_components/ -o firmware.swu
3. 引导加载程序(Bootloader)
U-Boot(主流选择):
支持 A/B 分区切换(通过环境变量如 bootcmd)。
需配置安全启动(Secure Boot)以验证内核和根文件系统的签名。
替代方案:GRUB2(适用于 x86 设备)。4. 固件镜像
内核(Kernel):需与设备硬件兼容(如 ARM/x86 架构)。
根文件系统(RootFS):支持 ext4、squashfs 或 UBIFS(针对 NAND 闪存)。
设备树(Device Tree):描述硬件配置(针对 ARM 设备)。
SWupdate
SWupdate 特征介绍:
Software Management on embedded systems — Embedded Software Update Documentation 2025.05 documentation
安装介质支持
- 存储介质广泛:支持在嵌入式介质(如 eMMC、SD、Raw NAND、NOR 和 SPI-NOR flash)上进行安装,能够适应不同嵌入式设备的存储需求。
- 多种更新方式:对于整个镜像,可作为 SD 卡上的分区或 MTD 分区进行更新,满足不同场景下的更新需求。
镜像构建与描述
- 特定格式与描述文件:镜像以指定的 cpio 格式构建,且必须包含一个描述文件,用于说明需要更新的软件信息。
- 结构化描述语言:默认使用 libconfig 库作为解析器,采用类似 JSON 的描述方式,也可以使用 Lua 语言编写自定义解析器,examples 目录中提供了使用 Lua 中的 XML 描述的示例。
分区操作
- 新分区模式与 UBI 卷管理:新分区模式与 UBI 卷相关,SWUpdate 可以重新创建 UBI 卷、调整其大小并复制新软件。
- 特殊 UBI 卷:名为“data”的特殊 UBI 卷在重新分区时用于保存和恢复数据,以保持用户数据的完整性。
文件系统更新
- 支持单个文件更新:支持更新文件系统中的单个文件,但必须明确描述该文件所在的文件系统位置。
校验机制
- 组件校验和:支持对图像中的单个组件进行校验和计算,确保更新数据的完整性。
脚本支持
- 多阶段脚本:支持在更新前、后运行命令,以及在更新开始处理数据前和成功完成后执行 Lua 钩子。
- 安装脚本:支持预安装脚本和后安装脚本,预安装脚本在流式处理程序处理完数据后、常规处理程序运行前执行,后安装脚本在更新镜像后运行。
网络安装
- 嵌入式 Web 服务器:使用嵌入式 Web 服务器(如 Mongoose Server)进行网络安装,也可以使用不同的 Web 服务器。
软件获取接口
- 多种接口支持:支持多种获取软件的接口,包括本地存储(如 USB、SD、UART 等)和 OTA/远程(如集成的网络服务器从远程服务器拉取,支持 HTTP、HTTPS 等协议)。
其他特性
- 压缩镜像支持:使用 zlib 和 zstd 库支持压缩镜像,支持 tarball(tgz 文件)。
- 分区设备支持:支持带分区的 USB-pen 或未分区盘(主要用于 Windows)。
- 文件系统内文件更新:支持更新文件系统中的单个文件,但需要明确描述该文件所在的文件系统位置。
- 变量设置与擦除:支持设置/擦除 U-Boot 变量、GRUB 环境块变量和 EFI Boot Guard 变量。
集成 Web 服务器
- 嵌入式网络安装:SWUpdate 集成了嵌入式 Web 服务器(如 Mongoose Server,采用 Lua 许可证下的版本),用户可以通过该服务器进行网络安装,实现远程固件更新。
- 可替换性:虽然默认使用 Mongoose Server,但用户也可以选择使用其他不同的 Web 服务器,以满足不同的项目需求和安全要求。
远程服务器交互
- 多协议支持:SWUpdate 支持从远程服务器拉取更新,支持 HTTP、HTTPS 等常见协议,确保更新过程的安全性和灵活性。
- 后端服务器集成:SWUpdate 设计为开放架构,可以与后端服务器进行通信以推出软件更新。当前版本支持与 hawkBit 服务器集成,同时允许添加其他后端服务器,以适应不同的软件更新管理需求。
兼容性检查
- 硬件兼容性验证:SWUpdate 可以配置为检查软件与硬件修订版之间的兼容性。软件镜像必须包含一个条目,声明该软件允许在哪些硬件修订版上运行。如果兼容性未通过验证,SWUpdate 将拒绝安装该软件,从而避免因不兼容导致的系统问题。
镜像提取
- 单一镜像管理:制造商可能要求使用一个包含多个设备软件的单一镜像,以简化管理和降低行政成本。SWUpdate 支持这种需求,它可以在不临时存储的情况下接收软件流,并仅提取目标设备所需的组件进行安装。
- 资源高效利用:这种镜像提取方式不仅减少了存储需求,还提高了更新过程的效率,因为只传输和安装必要的软件组件。
自定义处理器
- 灵活更新支持:SWUpdate 允许使用自定义处理器来安装 FPGA 固件、通过自定义协议更新微控制器固件等。这种灵活性使得 SWUpdate 能够适应各种复杂的嵌入式系统更新需求。
配置选项
- Kbuild 配置:SWUpdate 的功能可以通过“make menuconfig”进行启用或禁用,这一配置方式继承自 busybox 项目,提供了直观且易于使用的配置界面。
安全验证
- 镜像认证与验证:在安装之前,SWUpdate 会对镜像进行认证和验证,确保镜像的完整性和真实性。这通常通过数字签名和哈希校验来实现,防止恶意软件或损坏的镜像被安装到设备上。
断电安全
- 原子性更新:SWUpdate 确保更新过程的原子性,即如果更新过程中出现中断(如断电),设备不会处于部分更新的状态。这意味着更新要么完全成功,要么完全失败,从而避免了系统损坏的风险。
- 回滚机制:虽然直接提及的是断电安全,但 SWUpdate 的回滚机制也是其保障系统稳定性的重要手段之一。在更新失败时,SWUpdate 可以回滚到之前的版本,确保设备能够继续正常运行。
Swupdate在LinuxOTA升级中的作用
Swupdate工具在嵌入式Linux设备的OTA(Over-The-Air)升级方面具有重要应用,其核心作用及优势如下:
一、核心功能
- 支持多种更新传输方式,支持HTTP/HTTPS、FTP、TFTP、NFS等远程协议,以及本地存储(如USB、SD卡)加载更新包,满足不同场景需求。
- 灵活的镜像格式支持,可处理多种镜像格式,包括原始镜像(raw)、UBI(适用于NAND闪存)、ext4、squashfs(只读压缩文件系统)等,适配不同硬件环境。
- 多种更新模式
- 全镜像更新:完整替换文件系统或分区。
- 增量更新:仅更新变更部分,减少包大小和传输时间。
- 双分区更新(A/B分区方案):确保更新过程中的安全性和可靠性,避免因断电或中断导致设备变砖。
- 多镜像更新:在一次更新中处理多个镜像文件,提升效率。
- 支持更新验证,通过SHA256等校验和算法验证更新包的完整性,结合数字签名机制确保来源可信,防止恶意攻击和数据泄露。
- 失败回滚机制,在A/B分区方案中,若更新失败,系统可自动回滚到之前的稳定状态,保障设备可用性。
二、在Linux OTA升级中的应用
- 工业自动化,在不中断生产的前提下,通过Swupdate实现系统升级,确保设备持续稳定运行。
- 智能家居,支持远程推送固件更新,提升用户体验,同时保障设备安全性。
- 车载信息娱乐系统,定期推送功能更新和安全补丁,确保系统始终保持最新状态。
- 物联网(IoT)节点,确保边缘设备运行最新安全防护软件,降低安全风险。
三、技术优势
- 资源占用低,适用于资源受限的设备,支持零拷贝选项,避免临时文件复制,节省内存和存储空间。
- 高度可定制化,支持插件式架构和模块化设计,可根据需求灵活扩展功能,适配不同硬件平台。
- 安全可靠,提供完整性校验、签名验证、固件加密等功能,确保升级过程的安全性和私密性。
- 易集成性,可轻松集成到Yocto、Buildroot等嵌入式Linux构建系统中,简化开发流程。
一、升级方案架构
- 核心组件
- SWUpdate:负责解析升级包、验证签名、执行分区写入及回滚操作。
- 升级包格式:采用
.swu
格式,包含sw-description
(描述文件)和固件镜像(如内核、根文件系统)。- 双分区策略:使用 A/B 分区(如
rootfs_A
和rootfs_B
)或恢复分区(Recovery Mode),确保升级失败时可回滚。- 升级流程
- 触发升级:通过 HTTP/HTTPS 下载升级包,或从本地存储(如 USB/SD 卡)加载。
- 验证与解包:
- 校验
sw-description.sig
签名(基于 RSA/ECDSA)。- 解压
.swu
包,解析sw-description
中的镜像信息。- 写入目标分区:
- 根据描述文件,将镜像写入指定分区(如
rootfs_B
)。- 支持零拷贝(
installed-directly=true
)直接流式写入,避免临时文件占用内存。- 更新引导配置:修改 U-Boot 环境变量,设置下次启动分区为新镜像。
- 重启与验证:设备重启后,引导加载程序加载新分区,SWUpdate 可通过日志或状态文件确认升级结果。
二、关键实现步骤
准备升级包
生成描述文件 (
sw-description
):[images] kernel: filename="Image", device="/dev/mmcblk0p3", type="raw" rootfs: filename="rootfs.ext4", device="/dev/mmcblk0p4", type="raw"
打包升级包:
mkupdate -p update_package/ -o firmware.swu
其中
update_package/
包含Image
、rootfs.ext4
和sw-description
。
配置 SWUpdate
启用关键功能(通过
make menuconfig
或配置文件):CONFIG_SIGNED_IMAGES=y CONFIG_HASH_VERIFY=y CONFIG_A_B_UPDATE=y # 或 CONFIG_RECOVERY_MODE=y
U-Boot 集成:
在 U-Boot 脚本中添加环境变量切换逻辑:
setenv bootcmd "if test ${swupdate_status} = failed; then run boot_recovery; else run boot_primary; fi" setenv boot_primary "load mmc 0:2 ${kernel_addr_r} Image; bootm ${kernel_addr_r}" setenv boot_recovery "load mmc 0:3 ${kernel_addr_r} Image_recovery; bootm ${kernel_addr_r}"
执行升级
命令行升级:
swupdate -i firmware.swu -v -e "stable,now_A_next_B"
其中
-e
指定升级策略(如从 A 分区升级到 B 分区)。
脚本化升级:
在
sw-description
中添加预安装/后安装脚本,实现定制化逻辑(如硬件兼容性检查):[scripts] preinstall: "preinstall_check.sh" postinstall: "postinstall_reboot.sh"
三、容错与回滚机制
- 断电保护
- 使用
installed-directly=true
避免临时文件,减少写入中断风险。- 在 U-Boot 中记录升级状态(如
swupdate_status=failed
),确保重启后能回滚。- 手动回滚
- 若升级失败,通过 U-Boot 命令强制切换到旧分区:
setenv bootcmd "run boot_primary" saveenv
- 日志记录
- SWUpdate 将日志输出到串口或文件(如
/var/log/swupdate.log
),便于调试。