2. OTA升级基础

OTA(Over-The-Air)升级,指的是设备通过无线网络(Wi-Fi、蜂窝网络等)下载升级包,并由系统在本地完成校验、写入与重启生效的一整套机制。对 Android 设备而言,OTA 不只是“下载一个 zip 然后刷进去”,它涉及升级包格式、签名校验、分区布局、A/B 或非 A/B 切换策略、回滚保护等多个层面。理解这些基础概念,是后续制作与签名 OTA 包的前提。

一、OTA 的核心原理与升级类型

Android OTA 的本质是:升级包携带“目标系统镜像或差分补丁”,由 recovery 或 update_engine 在设备端执行写入。按升级方式,常见类型可分为以下几类:

  • 全量升级(Full OTA):升级包内包含完整的系统镜像或完整分区数据,不依赖设备当前版本,任何可兼容的旧版本都能直接升级到目标版本。
  • 增量升级(Incremental OTA):升级包只包含“从指定源版本到目标版本”的差分数据,体积小,但要求设备当前版本与差分基线严格匹配。
  • A/B 升级(无缝升级):设备存在两套系统槽位(slot A / slot B),升级写入非当前槽位,重启后切换,失败可回退,用户体验接近“无感”。
  • 非 A/B 升级(Recovery 升级):只有一套系统分区,升级时进入 recovery 写入,期间设备不可用,失败恢复能力相对较弱。

从“包内容”和“槽位机制”两个维度交叉,就形成了实际项目中最常见的组合:全量 A/B 包、增量 A/B 包、全量 recovery 包、增量 recovery 包。制作 OTA 包时,必须先明确目标设备采用哪种组合,否则生成的包可能无法被设备接受。

二、全量包与增量包的区别

全量包与增量包最直观的差异是体积,但真正影响制作与签名流程的,是它们对“源版本”的依赖程度。全量包不关心设备当前是什么版本,只要目标版本匹配即可;增量包则必须知道源版本,并且要求设备上的分区内容与差分基线完全一致,否则校验会失败。

对比维度 全量包(Full OTA) 增量包(Incremental OTA)
包体积 大,通常数百 MB 到数 GB 小,通常几十 MB 到数百 MB
源版本依赖 无,任意兼容旧版均可升级 强依赖,必须匹配指定源版本
制作输入 目标版本完整镜像 源版本镜像 + 目标版本镜像
校验方式 对完整分区数据做哈希与签名校验 对差分补丁应用后的结果做校验
失败风险 较低,数据完整 较高,源数据不一致即失败
典型场景 大版本升级、跨版本修复、出厂恢复 小版本修复、安全补丁、灰度推送
增量包体积小、推送成本低,但“源版本必须精确匹配”是硬约束。若设备被用户修改过系统分区,增量升级通常会直接失败,此时应回退到全量包。

三、应用场景与系统分区关系

OTA 升级最终要落到具体分区上。Android 设备常见分区包括 boot、system、vendor、product、odm、vbmeta 等。不同升级类型对分区的写入方式不同:

  • 全量包:通常直接写入完整分区镜像,或通过文件系统镜像整体替换。
  • 增量包:通过 bsdiff、imgdiff 等算法生成补丁,在设备端对旧分区数据打补丁后写入。
  • A/B 设备:升级写入非当前 slot 的对应分区,boot、system、vendor 等成对存在。
  • 非 A/B 设备:升级在 recovery 中对当前分区直接写入,需保证断电等异常情况下的可恢复性。

此外,vbmeta 分区与 AVB(Android Verified Boot)校验密切相关。升级后如果 vbmeta 中的哈希与分区实际内容不一致,设备可能无法启动。因此,制作 OTA 包时必须同步处理 vbmeta 的签名与校验数据。

OTA 升级类型与系统分区写入关系 全量包 Full OTA 包含完整分区镜像 不依赖源版本 体积大 · 兼容性强 适合大版本升级 写入:完整镜像 增量包 Incremental OTA 仅含差分补丁数据 强依赖源版本 体积小 · 推送成本低 适合安全补丁 / 灰度 写入:打补丁后写入 Android 系统分区布局 boot 内核 + ramdisk system Android 框架 vendor 厂商驱动 product 产品定制 odm ODM 定制 vbmeta AVB 校验数据 A/B 无缝升级机制 slot A 运行中 → 升级写入 slot B → 重启切换到 slot B 失败可回退到 slot A,用户几乎无感知 关键约束 增量包要求源分区数据与差分基线完全一致 vbmeta 必须与分区内容同步签名,否则无法启动

四、案例与常见误区

假设某厂商需要把一批设备从 Android 12 升级到 Android 13。若采用增量包,必须为每一个在网版本分别生成对应的差分包,例如 12.0.1→13.0.0、12.0.3→13.0.0。版本碎片越多,增量包数量越多,维护成本急剧上升。此时更合理的策略是:对主流版本提供增量包,对长尾版本统一推送全量包。

常见误区一:认为增量包一定比全量包“更好”。实际上,增量包对源版本一致性要求极高,一旦设备被 root、修改过分区或刷过第三方 ROM,增量升级几乎必然失败。误区二:忽略 vbmeta 与 AVB 校验,导致升级后设备卡在 bootloader 或反复重启。误区三:在非 A/B 设备上直接套用 A/B 的升级脚本,造成分区写入错位。

制作 OTA 包时,建议先确认三件事:设备是 A/B 还是非 A/B;目标分区有哪些;升级包采用全量还是增量。这三者决定了后续 ota_from_target_files 等工具的调用方式与签名流程。只有把升级类型与分区关系对齐,生成的 OTA 包才能被设备正确校验并生效。

# 典型 OTA 包制作入口(A/B 全量包示例)
ota_from_target_files \
  --path vendor/google/tools/releasetools \
  -k releasekey \
  --full \
  target_files.zip \
  ota_full.zip

# 增量包示例(需指定源 target_files)
ota_from_target_files \
  -k releasekey \
  -i source_target_files.zip \
  target_files.zip \
  ota_incremental.zip

理解 OTA 的定义、升级类型、全量包与增量包差异,以及它们与系统分区、A/B 槽位、AVB 校验之间的关系,是后续进行 OTA 包制作与签名的地基。只有先明确“升级什么、写到哪、怎么校验”,才能在实际项目中稳定地产出可用的 OTA 升级包。