3、升级策略总览:全量升级与增量升级、AB系统升级、双分区备份机制

升级策略这件事,说白了就是回答一个问题:新rootfs怎么安全地替换掉旧rootfs?

我这些年经手的嵌入式项目,从几块钱的MCU到上万的工控主板,升级方案翻来覆去就那么几种。但每种方案背后的取舍,很多人一开始没想透。今天我把它们掰开揉碎了讲清楚。

3.1 全量升级 vs 增量升级

这是最基础的分叉路口。先看对比:

维度 全量升级 增量升级
传输数据量 整个rootfs镜像(通常几十MB~几GB) 差异部分(通常几KB~几十MB)
升级耗时 较长(取决于镜像大小和传输带宽) 较短
实现复杂度 低(直接写分区) 高(需要差异算法、依赖分析)
失败风险 中等(写一半断电就砖) 较低(但依赖链复杂时可能出诡异问题)
适用场景 首次烧录、大版本跨越、安全补丁 频繁小版本迭代、OTA流量敏感

全量升级,我习惯叫它「暴力法」。直接把新rootfs镜像写到目标分区,覆盖旧的。简单、可靠、好调试。我在做智能网关项目时,初期一直用全量升级,因为设备数量少,网络带宽也够。但后来设备铺到上千台,每次升级要传200MB的镜像,用户等得骂娘——这才逼着我研究增量方案。

增量升级,核心是「只传变化的部分」。常见做法有两种:

  • 文件级增量:对比新旧rootfs的文件列表,只打包新增或修改的文件。工具如 rsync、diff + patch。
  • 块级增量:在块设备层面做差异,工具如 bsdiff、hdiffpatch。对二进制文件更友好。

关键点:增量升级不是万能的。如果新旧版本之间文件系统结构变化太大(比如从ext4换到squashfs),增量反而比全量更慢、更不可靠。我踩过这个坑——有一次为了省流量,硬用bsdiff对比两个完全不同的文件系统,结果补丁包比全量镜像还大。

我的建议:小版本迭代(patch级别)用增量,大版本升级(minor/major)用全量。混合策略最实用。

3.2 AB系统升级

AB系统,也叫「双系统切换」。这个名字很形象——设备里有两套完整的rootfs分区,A和B。当前运行在A,升级就写到B;下次启动切到B,如果B起不来,自动回退到A。

我画了一张图,帮你理解这个流程:

AB系统升级流程 AB系统升级流程 当前运行:A分区 rootfs A (active) 待机:B分区 rootfs B (inactive) 收到升级包 升级中:B分区 写入新rootfs 校验通过 完整性检查 OK 下次启动:切换到B A 变为待机分区 启动失败? 自动回退到A分区 校验失败或启动超时 核心思想:永远保证至少有一个可启动的rootfs。升级失败不影响当前运行系统。

AB系统的核心优势:零停机升级。升级过程中,当前系统照常运行。升级完成后,下次重启才切换。如果新系统起不来,bootloader检测到启动失败,自动切回旧分区。

注意:AB系统需要双倍存储空间。如果你的设备flash只有128MB,rootfs占60MB,那AB方案就塞不下。我曾在资源受限的IoT设备上硬推AB,结果不得不把rootfs压缩到极限,反而引入了性能问题。

实现AB系统,bootloader是关键。以U-Boot为例,它需要:

  • 读取某个存储位置(如eMMC的boot partition、NAND的特定block)的「启动计数器」和「成功标志」。
  • 如果当前分区启动失败(比如内核panic、init进程崩溃),计数器递增,超过阈值就切到另一个分区。
  • 如果启动成功,用户空间程序(如 update-engine)写入成功标志,重置计数器。

避坑指南:我曾经在某个项目里忘了处理「启动成功标志」的写入时机。结果每次启动都正常,但标志没写,bootloader以为启动失败,反复切换分区。最后设备在两个系统之间来回重启——俗称「重启循环」。解决方案很简单:在init脚本的最早阶段(挂载完必要文件系统后)就写入成功标志。

3.3 双分区备份机制

双分区备份,其实和AB系统是「近亲」。但侧重点不同:AB系统关注的是「升级过程中的可用性」,而双分区备份关注的是「升级失败后的可恢复性」。

常见的双分区布局有两种:

布局类型 分区A 分区B 数据分区 典型场景
对称AB rootfs + kernel rootfs + kernel 共享(如 /data) Android、ChromeOS
非对称备份 完整rootfs 最小恢复系统(recovery) 独立 路由器、智能家居网关

对称AB,就是前面讲的AB系统。两个分区完全一样,都可以作为主系统运行。

非对称备份,我更喜欢叫它「救急分区」。B分区只放一个最小化的Linux系统,能启动网络、挂载存储、执行升级命令就行。主系统A挂了,用户还能进B分区重新刷机。

我在做工业路由器项目时,用的就是非对称备份。主系统A有完整的Web界面、VPN、防火墙功能,占80MB。恢复分区B只有20MB,包含busybox、dropbear(SSH)、flashrom工具。有一次远程升级把A分区写坏了,客户打电话说设备连不上。我让他按住复位键上电,设备直接进恢复模式,我SSH进去重新刷了A分区——全程没派人去现场。

关键设计原则:

  • 恢复分区必须独立于主系统,不能依赖主系统的任何文件。
  • 恢复分区要能访问升级文件的存储介质(如SD卡、U盘、网络服务器)。
  • bootloader要提供进入恢复模式的触发方式(如GPIO检测、按键组合)。

3.4 如何选择?

没有银弹。我列一个决策清单,你可以对着自己的项目条件打勾:

  • 存储空间充足(>2倍rootfs) → 优先考虑对称AB系统,体验最好。
  • 存储空间紧张 → 全量升级 + 非对称恢复分区,或者增量升级 + 单分区。
  • 升级频率高(每月多次) → 增量升级 + AB系统,节省流量和时间。
  • 设备无人值守(如野外基站) → 必须AB系统,自动回退是刚需。
  • 法规要求(如医疗、工控) → 双分区备份 + 签名校验,缺一不可。

嗯,升级策略这块,说白了就是「空间换时间」和「复杂度换可靠性」的权衡。没有绝对的好坏,只有适不适合你的产品。