4. OTA升级包结构

一个完整的 Android OTA 升级包,本质上是一个经过签名的 ZIP 归档文件。它既不是简单的“固件压缩包”,也不是可以随意解压替换文件的普通压缩包,而是由引导脚本、元数据、分区镜像载荷和签名信息共同组成的可校验、可执行升级流程的交付物。理解升级包内部结构,是排查升级失败、定制升级逻辑以及验证签名完整性的基础。

一、升级包整体目录结构

以 A/B 无缝升级包为例,解压后典型结构如下:

ota_update.zip
├── META-INF/
│   ├── com/android/otacert          # 签名证书
│   ├── CERT.RSA / CERT.SF / MANIFEST.MF
│   └── com/google/android/update-binary
│   └── com/google/android/updater-script
├── payload.bin                      # 分区镜像载荷(A/B 包核心)
├── payload_properties.txt           # 载荷属性(哈希、大小、偏移)
├── care_map.pb                      # 分区校验映射
└── metadata                         # 包元数据(部分包格式)

传统非 A/B 包则通常包含 system.new.dat、system.transfer.list、boot.img 等分区镜像文件,并依赖 updater-script 逐条执行挂载、格式化、写入操作。两种包格式的核心差异在于:A/B 包把升级逻辑下沉到 update_engine,由 payload.bin 驱动;非 A/B 包则把逻辑写在 updater-script 中,由 recovery 中的 update-binary 解释执行。

Android OTA 升级包内部结构关系图 ota_update.zip(已签名 ZIP 容器) META-INF/ MANIFEST.MF / CERT.SF CERT.RSA(签名证书) update-binary updater-script payload.bin 分区镜像数据块 增量/全量操作指令 哈希与校验信息 由 update_engine 解析 元数据文件 metadata payload_properties.txt care_map.pb 设备兼容性声明 升级执行流程 校验签名 CERT.RSA 解析载荷 payload.bin 写入分区 A/B 槽位切换 重启生效 slot 切换

二、META-INF:签名与执行入口

META-INF 目录承担两个职责:一是存放 ZIP 签名信息,二是存放升级执行入口。其中 MANIFEST.MF 记录包内每个文件的摘要,CERT.SF 对清单进行二次摘要,CERT.RSA 则保存用私钥签名的证书链。Recovery 或 update_engine 在升级前会先验证这三者,任何文件被篡改都会导致签名校验失败。

对于非 A/B 包,META-INF/com/google/android/ 下还有两个关键文件:update-binary 是一个可执行程序,负责解释脚本;updater-script 则是升级指令文本。A/B 包中这两个文件通常被简化或省略,升级逻辑由 payload.bin 和 update_engine 接管。

三、payload.bin:A/B 包的核心载荷

payload.bin 是 A/B 升级包中体积最大的文件,内部按“操作(InstallOperation)”组织,每个操作描述对某个分区的写入、替换或校验。它包含全量镜像数据或增量差分数据,并带有每个数据块的哈希。升级时 update_engine 读取 payload.bin,按操作顺序写入目标槽位,同时校验哈希,确保写入内容与包内声明一致。

与 payload.bin 配套的 payload_properties.txt 记录载荷的 SHA-256、文件大小、元数据大小和偏移量,供升级工具快速定位和校验。若该文件缺失或哈希不匹配,升级会在“载荷解析”阶段直接失败。

四、updater-script 与 metadata

updater-script 是传统 OTA 包的“升级脚本”,由 update-binary 逐行解释。常见指令包括:

mount("ext4", "EMMC", "/dev/block/bootdevice/by-name/system", "/system");
package_extract_file("boot.img", "/dev/block/bootdevice/by-name/boot");
set_progress(0.5);
unmount("/system");

它决定了分区挂载方式、镜像写入位置和进度反馈。脚本写错分区路径或挂载参数,是导致“升级成功但无法开机”的常见原因。

metadata 文件则用于声明包的兼容性信息,例如设备型号、版本号、时间戳、安全补丁级别等。部分包格式还会把 metadata 与 care_map.pb 配合使用,后者记录分区校验映射,用于升级后验证关键分区是否完整。

五、关键文件对比清单

文件/目录 作用 所属包类型 缺失后果
META-INF/CERT.RSA 存放签名证书,验证包完整性 A/B 与非 A/B 签名校验失败,拒绝升级
updater-script 定义分区挂载与写入指令 非 A/B 无法执行升级操作
payload.bin 承载分区镜像与操作指令 A/B 无升级数据,升级中止
payload_properties.txt 记录载荷哈希与大小 A/B 无法校验载荷,升级失败
metadata 声明设备兼容性与版本信息 部分包格式 兼容性检查缺失,可能误刷
care_map.pb 记录分区校验映射 A/B 升级后校验不完整

六、案例与常见误区

场景:某厂商制作了 A/B 增量包,刷入后设备卡在开机动画。排查发现 payload.bin 中 system 分区的差分基准版本与设备当前版本不一致,导致写入后的镜像哈希校验失败。解决方式是确认源版本与目标版本匹配,并重新生成增量载荷。

误区一:把 OTA 包当成普通 ZIP 解压后替换文件再压缩。这样会破坏 MANIFEST.MF 与 CERT.SF 的摘要关系,签名必然失败。

误区二:认为 A/B 包不需要 updater-script 就“没有脚本”。实际上升级逻辑被编译进 payload.bin 的操作序列中,只是不再以文本脚本形式出现。

误区三:忽略 metadata 与 care_map.pb,导致跨型号刷机或升级后分区校验缺失,埋下稳定性隐患。

掌握升级包目录结构,重点不是记住每个文件名,而是理解“签名层—元数据层—载荷层—执行层”的分工:META-INF 保证包可信,metadata 与 care_map.pb 保证包适用且可校验,payload.bin 或 updater-script 决定数据如何写入分区。只有四层协同正确,OTA 升级才能安全、完整地落地。