3、AB分区升级流程:升级包下载、升级包校验、写入非活跃分区、切换槽位、重启生效

AB分区的升级流程,说白了就是一套「先准备好,再切换」的原子操作。我最早接触这个机制时,觉得它跟双缓冲渲染有点像——你在后台画好下一帧,然后瞬间切过去。嗯,本质上确实如此。

整个流程可以拆成五个关键步骤。每一步都有坑,我一个个说。

3.1 升级包下载

升级包通常是一个完整的系统镜像,也可能是差分包。下载阶段,系统会把包写入cache分区或data分区的临时目录。

这里有个容易被忽略的点:下载过程中不能断电。我遇到过一台设备,下载到80%时用户拔了电源,结果cache分区文件系统损坏,连正常系统都起不来了。后来我们强制要求:下载前先校验剩余电量,低于30%直接拒绝下载。

我的习惯:下载完成后立即计算一次SHA256,跟服务器下发的摘要比对。别等到校验阶段再做,早发现早处理。

3.2 升级包校验

校验不只是检查文件完整性。它通常包含三层:

校验层级 校验内容 失败处理
完整性校验 SHA256 / MD5 哈希比对 删除包,重新下载
签名校验 RSA/ECDSA 公钥验签 标记包无效,记录日志
元数据校验 版本号、硬件兼容性、分区大小 拒绝升级,提示不兼容

签名校验是安全底线。我记得有一次,测试团队拿了一个自编译的镜像刷进去,签名校验没通过,系统直接拒绝写入。嗯,这堵墙必须砌死。

我曾经踩过的坑:元数据校验里忘了检查分区大小。结果升级包里的system镜像比实际分区大了200MB,写入到一半直接报错,两个分区都处于不一致状态。从那以后,我强制要求校验阶段必须比对分区大小 ≥ 镜像大小 + 预留空间。

3.3 写入非活跃分区

这是AB分区最核心的一步。系统当前运行在slot A,那么升级包就写入slot B。反过来也一样。

写入过程不是简单的dd复制。它通常包含:

  • 分区格式化:先擦除非活跃分区的数据,避免残留数据干扰
  • 镜像写入:按块写入,每写一块校验一次CRC
  • 增量更新:如果是差分包,需要先读取活跃分区的基线数据,再应用补丁

写入过程中如果发生意外(比如掉电),最多是非活跃分区损坏,活跃分区纹丝不动。这就是AB分区最大的价值——写入操作与运行环境完全隔离。

关键指标:写入速度通常受限于闪存性能。我见过最慢的设备,写入一个2GB的system镜像花了12分钟。这种情况下,我会建议用户插着电源升级,或者做成后台静默升级。

3.4 切换槽位

写入完成后,系统不会立刻切换。它需要做两件事:

  1. 标记新分区为可启动:在misc分区或vbmeta中写入slot B的启动计数
  2. 设置启动次数:通常设为1,表示「下次启动尝试一次,失败就回滚」

切换槽位的操作是元数据写入,不是物理跳线。它修改的是bootloader读取的启动参数。我习惯把这个过程叫做「扳道岔」——火车(bootloader)看到道岔指向B,就开进B轨道。

避坑指南:切换槽位前,一定要确保非活跃分区的所有数据已经刷写完成并且校验通过。我曾经见过一个案例,写入线程还没结束,切换线程就把槽位标记改了,结果启动时读到半截数据,直接挂掉。加一个sync()和fdatasync()能解决大部分问题。

3.5 重启生效

最后一步,重启。bootloader读取槽位标记,发现slot B被标记为「待启动」,于是加载slot B的内核和ramdisk。

重启后,系统会做一次启动验证:

  • 如果启动成功,用户空间的服务正常拉起,系统会把slot B标记为「启动成功」
  • 如果启动失败(比如内核panic、init崩溃),bootloader会在超时后自动回滚到slot A

这个回滚机制是AB分区最让人放心的设计。你想想看,就算新系统炸了,旧系统还在那里,重启一次就回来了。

注意:有些设备在重启后不会立即标记「启动成功」。它们会等用户解锁、输入密码、甚至运行几分钟后才确认。这是为了防止「启动成功但马上死机」的边界情况。我建议至少等30秒再确认,给关键服务留够初始化时间。

3.6 整体流程图

下面这张图把整个流程串起来了。你可以看到,每一步都有校验和回退路径,保证系统在任何异常情况下都能恢复。

AB分区升级流程图 AB分区升级完整流程 ① 下载升级包 ② 校验升级包 校验失败 → 删除重下 ③ 写入非活跃分区 写入失败 → 保持原槽位 ④ 切换槽位 ⑤ 重启生效 ⑥ 启动验证 启动成功 → 标记OK 启动失败 → 回滚到A 说明:每一步都有异常处理路径,保证系统在任何异常情况下都能恢复到可用状态

3.7 关键参数速查表

最后,我整理了一份常用参数表。你在实现或调试AB分区升级时,可以直接参考。

参数 典型值 说明
升级包存储路径 /cache/update.zip 或 /data/ota_package/ 取决于分区大小和策略
校验算法 SHA256 + RSA-2048 完整性+签名双重保障
写入块大小 4096 bytes 对齐闪存页大小,提升写入性能
槽位标记位置 misc 分区偏移 0x200 bootloader 启动时读取
启动验证超时 30 秒 超时未确认则触发回滚

嗯,以上就是AB分区升级的完整流程。每一步都不复杂,但串联起来就是一个非常健壮的升级体系。你想想看,从下载到重启,每个环节都有校验和回退,这才是工业级系统该有的样子。