11、升级包生成工具:ota_from_target_files脚本、brillo_update_payload工具、OTA配置参数详解

做Android系统升级开发,说白了就是跟升级包打交道。你写好了差分算法,搞定了分区布局,最后总得有个工具把这些东西打包成一个真正的、能刷到设备里的升级包。今天我就跟你聊聊这三个核心工具:ota_from_target_filesbrillo_update_payload,以及那些让人头疼的OTA配置参数。

我个人习惯把升级包生成工具分成两类:一类是给A/B分区用的,一类是给非A/B分区用的。前者用brillo_update_payload,后者用ota_from_target_files。嗯,这里要注意,Google在Android 11之后已经逐步把非A/B方案淘汰了,但老项目里你肯定还会碰到。

11.1 ota_from_target_files脚本:老牌工具,依然能打

这个脚本藏在build/tools/releasetools/目录下。它干的事情很简单:把你编译出来的target-files.zip,转成一个可刷写的OTA包。

你想想看,target-files.zip里装的是啥?是每个分区的镜像文件、签名信息、META目录下的各种配置。ota_from_target_files就是把这些东西按你指定的策略重新打包。

核心用法:

# 生成完整升级包
ota_from_target_files \
  -n \
  -v \
  -k build/target/product/security/testkey \
  -i incremental_target_files.zip \
  target_files.zip \
  ota_update.zip

参数说明:

  • -n:不签名,调试时用。我建议正式发布时别加这个参数。
  • -v:输出详细信息,排查问题利器。
  • -k:指定签名密钥。我在项目中遇到过密钥路径写错导致升级包签名失败,设备死活不认包的情况。
  • -i:指定增量包的基础版本。没有这个参数就是完整包。

我曾经踩过一个坑:用-i生成增量包时,如果基础版本的target-files.zip里某个文件被删除了,但增量包里的脚本没处理好,刷机后设备直接变砖。后来我养成了一个习惯——每次生成增量包前,先跑一遍check_target_files_vintf做兼容性检查。

11.2 brillo_update_payload工具:A/B分区的专属武器

这个工具最早是Brillo项目(Android Things的前身)里用的,后来被移植到了AOSP。它专门用来生成payload.bin——也就是A/B分区升级用的那个二进制文件。

说白了,ota_from_target_files生成的是zip包,里面可能包含脚本、签名、校验文件。而brillo_update_payload生成的就是一个纯粹的二进制差分数据流。设备端拿到这个payload,直接往备用分区里写就行。

生成payload的命令:

brillo_update_payload \
  --source_image old_system.img \
  --target_image new_system.img \
  --output payload.bin \
  --properties_file payload_properties.txt

参数解析:

  • --source_image:基础版本的分区镜像。做增量升级时必须指定。
  • --target_image:目标版本的分区镜像。
  • --output:输出的payload文件。
  • --properties_file:属性文件,里面写版本号、哈希值等元信息。

我记得有一次,客户反馈升级包太大,OTA下载失败。排查后发现是brillo_update_payload生成的payload没有做压缩。后来我在命令里加了--compress bsdiff参数,包体积直接缩小了40%。

11.3 OTA配置参数详解:别小看这些细节

配置参数这东西,你看着不起眼,但出问题的时候往往就是它们搞的鬼。我整理了一份常用参数表,你直接拿去用:

参数名 作用 我的建议
block_size 差分计算时的块大小,默认4096字节 别改,除非你很清楚自己在做什么
minor_version payload格式版本号 保持跟设备端update_engine一致
max_timestamp 升级包允许的最大时间戳 我一般设成当前时间+7天,防止证书过期
postinstall 升级完成后执行的脚本路径 注意脚本权限,我吃过755写成644的亏
verify 是否在生成时做完整性校验 建议开启,虽然慢一点但安全

这里有个容易忽略的点:minor_version。Android 8.0用的是2,Android 9.0是3,Android 10之后是4。如果你生成的payload版本号比设备端update_engine支持的高,设备会直接拒绝升级。我曾经因为这个问题排查了整整两天,最后发现是编译环境里的SDK版本跟设备不匹配。

避坑指南:

我曾经在生成payload时忘记设置--properties_file,结果设备端拿不到版本号,升级到一半卡在"验证中"界面。后来我写了个脚本,每次生成payload后自动检查properties文件里的字段是否完整。你最好也这么做。

11.4 知识体系总览

为了让你更直观地理解这三个工具之间的关系,我画了一张图:

升级包生成工具知识体系 target-files.zip ota_from_target_files 非A/B分区升级包 brillo_update_payload A/B分区payload.bin ota_update.zip payload.bin + properties OTA配置参数(block_size等) 虚线表示配置参数影响所有工具的输出行为

从这张图你可以看到,整个流程是单向的:target-files.zip作为输入,经过两个工具分别处理,输出不同类型的升级包。而OTA配置参数就像调味料,影响着最终产物的质量。

最后说一句:不管用哪个工具,生成完升级包后一定要做一次本地模拟升级测试。我见过太多人图省事,直接推到设备上,结果刷完开不了机。你花10分钟测试,可能省下10小时的排障时间。


公众号:蓝海资料掘金营,微信deep3321