1. 课程导入

在Android系统交付与维护中,OTA(Over-The-Air)升级是最常见、也最关键的版本更新方式。无论是手机厂商推送安全补丁、修复系统缺陷,还是为定制设备增加新功能,最终都要落到一个可被设备端recovery或A/B更新引擎识别、校验并写入的升级包上。而“制作”与“签名”正是这条链路中决定升级包能否被正确安装、能否通过安全校验的两个核心环节。本课程将围绕这两个环节,从概念、工具、流程到排障,系统讲解Android OTA升级包的完整生产方法。

一、学习目标:从“会打包”到“懂机制”

本课程不是简单地教几条命令,而是希望学习者建立完整的OTA升级包生产认知。完成学习后,应达到以下目标:

  • 理解OTA升级包的基本形态,包括完整包(full OTA)与增量包(incremental OTA)的差异、适用场景与生成条件。
  • 掌握A/B与non-A/B(recovery)两种升级机制对升级包结构、元数据和签名方式的不同要求。
  • 能够使用ota_from_target_files、ota_from_target_files.py等工具,从target-files生成可刷写的OTA包。
  • 理解签名在OTA中的安全作用,掌握使用signapk、openssl及release-key对升级包进行签名的流程。
  • 能够定位常见失败,如签名校验失败、增量包生成失败、payload属性不匹配、设备端安装中断等。
  • 建立从源码编译、target-files生成、OTA制作、签名、验证到发布的完整工程视角。

核心判断:一个OTA升级包是否“合格”,不只看它能否生成,而要看它能否在目标设备上通过签名校验、版本校验、分区校验,并最终完成写入与重启。

二、核心概念:升级包、target-files与签名

要理解OTA制作,先要理清三个基础对象。第一是target-files,它是Android构建系统输出的中间产物压缩包,通常位于out/target/product/<device>/obj/PACKAGING/target_files_intermediates/下,包含系统镜像、分区信息、文件列表、脚本和元数据,是生成OTA包的“原料”。第二是OTA升级包,它可以是完整包,也可以是增量包,内部通常包含META-INF/com/google/android/updater-script、payload.bin、payload_properties.txt、care_map等文件。第三是签名,它通过私钥对升级包或payload进行数字签名,设备端用预置公钥验证,确保升级包来源可信、内容未被篡改。

在A/B机制中,升级包的核心是payload.bin,它由update_engine解析并写入非当前槽位;在non-A/B机制中,升级包更多依赖recovery执行updater-script完成分区写入。两种机制对签名和校验的要求不同,但都离不开“包—签名—校验—安装”这条主线。

Android OTA 升级包制作与签名 · 整体框架 从源码构建到设备端校验安装的完整链路 源码与配置 AOSP / 厂商代码 device / vendor 配置 编译构建 make otapackage 生成 target-files OTA 包制作 完整包 / 增量包 payload / updater-script 签名与校验 signapk / release-key payload 签名 关键中间产物:target-files.zip system.img / vendor.img / boot.img / META / file_list / care_map 等 A/B 升级机制 payload.bin + update_engine 写入非当前槽位,重启切换 支持无缝升级与回滚 non-A/B(recovery)机制 updater-script + recovery 直接写入 system / vendor 等分区 依赖脚本与分区校验 设备端:签名校验 → 版本校验 → 写入 → 重启生效

三、整体框架:从源码到设备端的五段链路

结合上图,可以把整个OTA生产链路拆成五段。第一段是源码与配置准备,包括AOSP或厂商代码、device配置、vendor配置、分区表与版本号定义。第二段是编译构建,通过make otapackage或分步构建生成target-files。第三段是OTA包制作,使用ota_from_target_files生成完整包或增量包,并生成payload及属性文件。第四段是签名与校验,对包或payload进行签名,确保设备端能验证通过。第五段是设备端安装,由recovery或update_engine执行校验、写入和重启。

这五段链路中,最容易出问题的往往不是“生成”本身,而是“生成出来的包能否被目标设备接受”。因此,学习时要把签名、版本、分区、payload属性放在与打包同等重要的位置。

四、方法流程:一条可复用的制作主线

下面给出一个典型的A/B设备OTA制作主线,便于建立操作框架:

# 1. 编译生成 target-files
source build/envsetup.sh
lunch aosp_device-userdebug
make otapackage -j8

# 2. 定位 target-files
ls out/target/product/<device>/obj/PACKAGING/target_files_intermediates/

# 3. 生成完整 OTA 包
./build/tools/releasetools/ota_from_target_files \
  -k vendor/releasekey \
  target_files.zip full_ota.zip

# 4. 生成增量 OTA 包
./build/tools/releasetools/ota_from_target_files \
  -i old_target_files.zip \
  -k vendor/releasekey \
  new_target_files.zip incremental_ota.zip

# 5. 校验签名与包结构
unzip -l full_ota.zip
java -jar signapk.jar -w releasekey.x509.pem releasekey.pk8 full_ota.zip signed_ota.zip

对于non-A/B设备,流程类似,但生成物中会包含updater-script,且签名对象通常是整个OTA zip包。对于A/B设备,除了外层zip签名,还要关注payload本身的签名与payload_properties.txt中的哈希、尺寸等属性。

五、案例与场景:一次典型的增量升级失败复盘

某定制设备在推送增量包时,设备端提示“payload verification failed”。排查发现,制作增量包时使用了旧的target-files,但签名时却用了新的release-key,导致payload属性中的哈希与签名不匹配。修正方法是:确保增量包基于正确的源版本target-files生成,并使用与设备预置公钥对应的私钥签名。这个案例说明,OTA制作不是单点操作,而是“源版本—目标版本—签名密钥—设备公钥”四者必须严格对应。

常见误区:只关注OTA包能否生成,忽略签名密钥与设备预置公钥的匹配关系;或者把userdebug版本的签名密钥误用于user版本发布包,导致设备端校验失败。

六、学习路径与关键清单

建议按“概念—工具—实操—排障—发布”的顺序推进。先理解A/B与non-A/B差异,再掌握target-files与ota_from_target_files,随后完成完整包与增量包制作,最后学习签名、校验和常见错误定位。下表给出本课程后续将反复使用的关键对象清单:

关键对象 作用 常见位置/命令 易错点
target-files.zip OTA制作的原料,包含镜像与元数据 out/target/product/<device>/obj/PACKAGING/ 版本与设备不匹配
ota_from_target_files 生成完整包或增量包 build/tools/releasetools/ 增量包源版本错误
payload.bin A/B升级的实际写入数据 OTA zip内部 属性与签名不一致
updater-script non-A/B升级的执行脚本 META-INF/com/google/android/ 分区路径写错
release-key 对OTA包或payload签名 vendor/releasekey 或自定义密钥 与设备公钥不匹配
signapk.jar 执行zip包签名 build/tools/signapk/ 漏签或重复签名