1. 课程导入

在 Android 系统演进中,OTA 升级体验始终是用户感知最强、工程链路最长的环节之一。传统单分区方案在升级时需要进入 Recovery 模式,设备会经历数分钟黑屏或进度条等待,一旦写入中断还可能导致系统无法启动。A-B 分区机制通过“双系统槽位 + 原子切换”的方式,把升级过程从“停机写入”变成“后台写入、重启切换”,从而实现用户几乎无感的无缝升级。本课程将围绕这一机制,从分区结构、启动链路、升级流程、回滚策略到工程落地,系统讲解 Android A-B 分区与无缝升级的完整知识体系。

一、学习目标:从“知道”到“能落地”

本课程不是单纯的概念科普,而是面向 Android 系统开发、BSP 适配、OTA 平台建设和测试验证的工程化课程。完成学习后,你应当能够达到以下目标:

  • 理解结构:掌握 A/B 分区的物理布局、slot 元数据、boot control 抽象层以及 super 动态分区与 A/B 的关系。
  • 掌握流程:能够描述从 OTA 包下载、payload 校验、后台写入非活动槽位,到重启切换、标记 successful 的完整状态机。
  • 具备排障能力:能根据 bootctl、update_engine 日志和 slot 状态判断升级失败发生在下载、写入、切换还是启动阶段。
  • 完成工程配置:能够在 BoardConfig、fstab、Android.bp 等配置中正确启用 A/B 与 Virtual A/B,并理解压缩、快照、合并等关键参数。
  • 建立验证思维:能够设计覆盖正常升级、断电中断、回滚、降级限制等场景的测试用例。

核心判断:学习 A/B 分区的关键不是记住“有两个分区”,而是理解“活动槽位与非活动槽位如何切换、切换后如何确认、确认失败后如何回滚”。这三件事构成了无缝升级的工程闭环。

二、核心价值:为什么 Android 必须走向 A-B

单分区升级的本质矛盾在于:系统运行的分区与要被覆盖的分区是同一个。写入过程中断电、校验失败或镜像损坏,都会直接破坏可启动系统。A-B 分区把“运行”和“更新”解耦:当前运行在 slot A,升级包写入 slot B;写入完成后只修改一次 bootloader 可读的槽位元数据,重启即从 B 启动。若 B 启动失败,bootloader 可自动回退到 A。这种设计带来四个直接价值:

价值维度 单分区方案 A-B 无缝升级
用户可用性 升级期间设备不可用 后台写入,重启即用
失败恢复 可能变砖,需 Recovery 修复 自动回滚到旧槽位
升级粒度 整包覆盖,风险集中 按 slot 原子切换
存储成本 占用较低 需要额外槽位空间,可用 Virtual A/B 缓解

对于手机、平板、车机和 TV 等设备,A/B 已成为 Android 10 以后主流 GMS 设备的默认要求。理解它,等于掌握了现代 Android 系统升级的主干道。

三、整体知识框架:五层结构一张图看清

本课程的知识框架可以拆成五个层次:硬件与分区层、启动与引导层、升级引擎层、应用与策略层、验证与运维层。下图给出各层的关键对象与它们之间的数据/控制关系,后续章节将逐层展开。

Android A-B 分区与无缝升级 · 五层知识框架 ① 硬件与分区层 boot_a / boot_b · system_a / system_b · vendor_a / vendor_b · super 动态分区 · misc / metadata ② 启动与引导层 Bootloader · slot 元数据 · boot_control HAL · A/B 启动决策 · 回滚触发条件 ③ 升级引擎层 update_engine · payload.bin · 差分/全量 · 后台写入 · Virtual A/B 快照与合并 ④ 应用与策略层 OTA 客户端 · 升级策略 · 下载与校验 · 用户提示 · 重启时机控制 ⑤ 验证与运维层 bootctl 状态检查 · update_engine 日志 · 断电/回滚测试 · 灰度发布与指标监控 验证反馈驱动策略与配置修正

这张框架图同时给出了学习顺序:先建立分区与启动的“静态结构”,再理解升级引擎的“动态流程”,最后用验证与运维闭环把工程能力固化下来。

四、实战路线图:从环境搭建到完整升级验证

为了让知识真正可操作,本课程设计了一条由浅入深的实战路线。你可以把它当作学习地图,也可以当作项目落地检查表。

  1. 环境与配置:在 BoardConfig.mk 中启用 AB_OTA_UPDATER := true,配置 AB_OTA_PARTITIONS,并确认 fstab 中 slotselect 挂载参数正确。
  2. 构建与产物:生成包含 payload.bin 的 OTA 包,理解 ota_from_target_files 与 delta_generator 的作用。
  3. 升级执行:通过 update_engine_client 触发升级,观察后台写入非活动槽位的过程。
  4. 切换与确认:重启后检查 bootctl get-current-slot 与 bootctl get-slot-suffix,确认新槽位已激活并标记 successful。
  5. 异常演练:模拟写入中断、启动失败和回滚,验证 bootloader 的自动回退能力。
  6. Virtual A/B 进阶:理解快照、COW 与合并机制,掌握存储空间不足时的处理策略。
# 典型状态检查命令
adb shell bootctl get-current-slot
adb shell bootctl get-slot-suffix
adb shell bootctl is-slot-marked-successful 0
adb shell update_engine_client --status
adb shell dumpsys android.hardware.boot.IBootControl/default

学习建议:每学完一个模块,都在真机或模拟器上执行一次对应命令,把“文字流程”变成“可观察状态”。A/B 升级的很多问题,只有看到 slot 状态和 update_engine 日志才能真正定位。

五、常见误区与复盘提醒

初学者最容易陷入三个误区。第一,认为“有 A/B 分区就一定无缝”,实际上如果 OTA 客户端在下载后强制立即重启,用户体验仍然会中断。第二,把 Virtual A/B 当成“不需要额外空间”,它只是用快照和 COW 延迟合并,空间不足时依然会失败。第三,忽略 bootloader 与 boot_control HAL 的适配,导致 slot 元数据写入失败,升级卡在“写入完成但无法切换”。

复盘重点:无缝升级的成败往往不在升级包本身,而在“切换决策”和“失败回滚”这两个边界条件。后续章节会反复回到这两个点,请务必建立“状态机思维”,而不是只记命令。

接下来,课程将从 A/B 分区的物理结构与 slot 元数据讲起,逐步深入到启动链路、升级引擎、Virtual A/B 和工程验证。你只需要带着一个问题进入每一节:这个对象在升级状态机中处于哪个位置,它失败时会发生什么? 带着这个问题,整门课程的知识就会自然串联起来。