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 系统升级的主干道。
三、整体知识框架:五层结构一张图看清
本课程的知识框架可以拆成五个层次:硬件与分区层、启动与引导层、升级引擎层、应用与策略层、验证与运维层。下图给出各层的关键对象与它们之间的数据/控制关系,后续章节将逐层展开。
这张框架图同时给出了学习顺序:先建立分区与启动的“静态结构”,再理解升级引擎的“动态流程”,最后用验证与运维闭环把工程能力固化下来。
四、实战路线图:从环境搭建到完整升级验证
为了让知识真正可操作,本课程设计了一条由浅入深的实战路线。你可以把它当作学习地图,也可以当作项目落地检查表。
- 环境与配置:在 BoardConfig.mk 中启用
AB_OTA_UPDATER := true,配置AB_OTA_PARTITIONS,并确认 fstab 中slotselect挂载参数正确。 - 构建与产物:生成包含
payload.bin的 OTA 包,理解ota_from_target_files与delta_generator的作用。 - 升级执行:通过
update_engine_client触发升级,观察后台写入非活动槽位的过程。 - 切换与确认:重启后检查
bootctl get-current-slot与bootctl get-slot-suffix,确认新槽位已激活并标记 successful。 - 异常演练:模拟写入中断、启动失败和回滚,验证 bootloader 的自动回退能力。
- 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 和工程验证。你只需要带着一个问题进入每一节:这个对象在升级状态机中处于哪个位置,它失败时会发生什么? 带着这个问题,整门课程的知识就会自然串联起来。