1. 课程导入

Android系统升级看似只是“推送一个OTA包、重启一次设备”,但在工程实践中,它是一条横跨Bootloader、分区表、A/B槽位、AVB校验、OTA客户端、Recovery与云端灰度系统的完整链路。任何一环设计不当,都可能让设备停在开机Logo、反复重启,甚至彻底变砖。本课程的目标,是把“升级失败”从一次事故,转化为一套可预测、可验证、可回滚、可复盘的工程能力。

本课程的核心命题只有一句话:让每一次升级都具备确定的回退路径,让每一次故障都能被快速定位与恢复。

一、学习目标:从“会刷机”到“会设计恢复体系”

很多工程师对升级回滚的理解停留在“进Recovery双清”“用fastboot刷回旧包”。这只是操作层面。本课程希望建立四个层次的能力:

  • 原理层:理解A/B无缝升级、非A/B升级、Recovery升级三种模式的差异,理解slot、boot control、AVB、dm-verity、payload.bin、super分区等关键机制。
  • 设计层:能够为产品设计回滚策略,包括保留旧槽位、设置回滚窗口、定义回滚触发条件、规划数据兼容与降级限制。
  • 实操层:掌握fastboot、adb、OTA侧载、logcat、dmesg、bootctl、avbctl等工具在故障现场的使用方法。
  • 复盘层:能够从一次升级失败中提取根因,形成检查清单、灰度策略与自动化验证用例,避免同类问题重复发生。

二、核心概念:升级、回滚、恢复不是三件事

升级(Upgrade)是把新版本系统写入设备并使其可启动;回滚(Rollback)是在新版本不可用时切回已知可用版本;恢复(Recovery)是在两者都异常时,通过最小可用环境修复设备。三者共享同一套底层设施:分区、槽位、引导控制与校验链。

在A/B系统中,设备通常有两个槽位slot_a和slot_b。当前运行槽位称为current slot,待升级槽位称为target slot。OTA写入非当前槽位,重启后由Bootloader根据boot control的标记决定启动哪个槽位。如果新槽位启动失败,系统可以标记该槽位为unbootable,并回退到旧槽位。这就是“无缝回滚”的基础。

# 查看当前槽位与槽位状态
adb shell bootctl get-current-slot
adb shell bootctl get-slot-suffix
adb shell bootctl is-slot-marked-successful 0
adb shell bootctl is-slot-marked-successful 1

# 查看AVB与dm-verity状态
adb shell avbctl get-verity
adb shell avbctl get-verification
adb shell dmesg | grep -i "avb\|verity\|slot"

非A/B设备没有双槽位,升级通常依赖Recovery写入/system、/vendor等分区。一旦写入中断或新系统无法启动,回滚能力取决于是否保留了可用的旧镜像或是否支持从SD卡、U盘、fastboot重新刷写。因此,非A/B方案必须额外设计“恢复介质”和“强制进入Recovery”的路径。

三、整体知识框架:一条从云端到Bootloader的链路

下图把本课程的知识框架压缩为一条纵向链路:云端发布与灰度、设备端OTA客户端、分区与槽位、引导与校验、启动结果上报、回滚与恢复。每一层都有对应的失败模式和观测点。

Android升级回滚与故障恢复工程 · 知识框架 云端 → 设备端 → 分区/槽位 → 引导/校验 → 启动结果 → 回滚/恢复 ① 云端发布与灰度 OTA包管理 · 版本策略 · 灰度比例 · 暂停/回滚指令 · 设备分组 ② 设备端OTA客户端 下载校验 · payload解包 · 写入目标槽位 · 更新boot control · 重启调度 ③A 分区与槽位(A/B) slot_a / slot_b · boot / system / vendor super动态分区 · 元数据 · 回滚窗口 ③B 分区与恢复(非A/B) Recovery · cache · sdcard · fastboot 旧镜像保留 · 强制恢复入口 ④ 引导与校验链 Bootloader · AVB2.0 · vbmeta · dm-verity · boot control · 启动计数 ⑤A 启动成功 标记successful · 上报版本 · 清理旧槽位 ⑤B 启动失败 标记unbootable · 回退旧槽位 · 进入恢复 回滚/恢复路径

四、实战路线图:30章如何组织

课程按“基础机制 → 升级实现 → 回滚设计 → 故障恢复 → 工程化复盘”推进。前几章建立分区、槽位、AVB与OTA包结构的共同语言;中段进入A/B与非A/B升级的具体实现、boot control操作、payload写入与校验;后段聚焦回滚触发条件、降级限制、数据兼容、Recovery修复、fastboot救援与云端灰度联动;最后以真实故障案例和检查清单收束。

阶段关键问题产出物
基础机制分区、槽位、AVB、OTA包如何协同机制图、关键命令清单
升级实现如何安全写入目标槽位并切换升级流程、校验脚本
回滚设计何时回滚、回滚到什么版本、数据怎么办回滚策略、降级兼容矩阵
故障恢复无法启动、校验失败、槽位损坏如何救恢复路径、救援命令集
工程化复盘如何灰度、监控、复盘与防复发灰度方案、检查清单、复盘模板

五、典型场景与常见误区

场景一:A/B设备OTA后卡在开机动画。此时不要急着重刷,先通过adb reboot bootloader或按键组合进入Bootloader,检查当前槽位与槽位标记。如果目标槽位被标记为unbootable,说明系统已经尝试回退。此时应抓取dmesg与logcat,确认是AVB校验失败、system挂载失败还是SELinux拒绝。

场景二:非A/B设备升级中断,Recovery无法挂载/system。需要确认cache分区是否可写、OTA包是否完整、签名是否匹配。若Recovery本身损坏,只能依赖fastboot或外部恢复介质。

常见误区:把“回滚”等同于“重新刷旧包”。真正的回滚设计必须提前回答三个问题:旧槽位是否保留?旧版本数据是否兼容?回滚后如何再次升级?如果这三个问题没有答案,回滚就只是一次高风险的现场操作。
建议从第一天就建立“升级可观测性”:记录当前槽位、目标槽位、AVB状态、启动计数、OTA包哈希、升级耗时与失败阶段。这些字段会在后续排障中反复用到。

本课程不追求记住所有命令,而是建立一套判断顺序:先看槽位与引导状态,再看校验链,再看分区与数据,最后才考虑重刷。顺序对了,故障恢复就从“碰运气”变成“按图索骥”。