Android OTA 之 升级包编译机制

前面介绍了OTA的一些基本概念和常用的两种OTA升级方式(recovery和update_engine),基于之上本篇继续介绍一下OTA包的编译生成机制。

一、编译OTA包

编译生成OTA包的方式非常多,并且不同平台还有不一样的命令,在加上android 8.0引入的Android Treble架构,导致OTA包的制作方式存在一些列变化。本章就依次把他们的脉络进行梳理。

1、传统方式

在Android Treble化之前,AOSP已经提供了默认的方式来生成OTA升级包,主要是使用了如下几个命令:

  • source build/envsetup.sh
  • lunch <target>
  • make -jN ---> 形成完成全量编译
  • make otapackage ---> 生成完整OTA包
  • make partialotapackage ---->生成部分OTA包
  • make otardppackage ----->生成动态分区OTA包/使用场景非常少

make otapackage命令实际上是执行的aosp/build/make/core/Makefile中如下代码:

1)build-ota-package-target的调用

如上执行make otaxxx命令最终都是调用call build-ota-package-target函数,此函数的解析如下:

bash 复制代码
$(call build-ota-package-target,$@,-k $(KEY_CERT_PAIR) --output_metadata_path $(INTERNAL_OTA_METADATA))
# call 是makefile的函数调用语法,这里调用的是build-ota-package-target函数,
# 传递KEY_CERT_PAIR和INTERNAL_OTA_METADATA参数

# build-ota-package-target函数定义
# 此函数核心代码调用了OTA_FROM_TARGET_FILES指定的脚本文件
define build-ota-package-target
PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$(dir $(ZIP2ZIP)):$$PATH \
    $(OTA_FROM_TARGET_FILES) \
        --verbose \
        --path $(HOST_OUT) \
        $(if $(OEM_OTA_CONFIG), --oem_settings $(OEM_OTA_CONFIG)) \
        $(if $(BOOT_VAR_OTA_CONFIG), --boot_variable_file $(BOOT_VAR_OTA_CONFIG)) \
        $(2) \
        $(patsubst %.zip,%,$(BUILT_TARGET_FILES_PACKAGE)) $(1)
endef

2)ota_from_target_files工具的指定

其中OTA_FROM_TARGET_FILES的定义如下,指定了out目录下的生成的ota_from_target_files可执行文件

那么真的是out目录吗? 我这里直接下个结论,是的,我们通常自己做ota包的步骤如下:

cd /out/host/linux-x86/bin/

ota_from_target_files -v -k 秘钥文件路径 target.zip文件路径 ota包输出路径

3)KEY_CERT_PAIR签名文件指定

如上执行make otaxxx命令的时候指定秘钥文件,即宏变量KEY_CERT_PATH指定的key文件路径,我们看看他的赋值链如下:

如上最后还是回到了应用签名key,针对这块机制可以参考https://blog.csdn.net/qq_27672101/article/details/156126737

4)out/dist输出路径

在最新高通平台Android 16上面,执行make会默认在out/dist目录生成target包:

然而我执行make otapackage命令却出现如下编译报错:

2、平台方式

原因为这条基线,高通构建系统已切换到 Soong + Ninja(AOSP 从 Android 7.0+ 逐步迁移,Android 10+ 完全默认)。otapackage 目标未被注册 → 通常是因为:

  • 设备配置(device/qcom/... 或 vendor/qcom/...)没有启用 Recovery 或 OTA 支持
  • 高通 BSP(Board Support Package)移除了传统 OTA 构建逻辑
  • 使用了 user/userdebug 以外的编译变体(但可能性较低)
  • Android 版本较新(如 Android 12+),默认使用 update_payload 而非 otapackage

make otapackage的操作方式只能针对Android Treble化之前。

在Treble化之后无论是高通平台还是MTK平台还是展锐平台,都对system和vendor进行了分离,即使用了两套aosp代码,整个编译流程从之前的单一源码编译转换成了:

  • 编译system侧代码
  • 编译vendor侧代码
  • 再进行合并,MTK使用split_build.py/高通使用build_image_standalone.py
  • 注意AOSP原生不支持分区合并,因此分区合并都是不同平台实现不一样

1)高通平台

那么target包的生成流程呢?这里列一下高通的解决方案,先看看高通的合并命令可以提供的参数:

python vendor/qcom/opensource/core-utils/build/build_image_standalone.py

--image super #表示进行分区合并

--qssi_build_path "{CODE_PATH}/{QSSI_PATH}" #指定system代码路径

--target_build_path . #指定target包输出路径

--merged_build_path . #指定合并后的分区输出路径

--target_lunch ${PRODUCT_NAME} #指定设备 lunch 名称

--output_ota #表示不仅要生成镜像,还要生成合并后的target_files.zip

如上命令参数--output_ota会把system侧的target包与vendor侧的target包进行合并:

2)MTK平台

MTK平台关于OTA升级我没有深入研究过,不过可以看到的它的原理实际上和上面的高通方式基本一致,如下在对system侧与vendor侧进行合并的时候,需要使用split_build.py工具,至于这个工具是原生的还是mtk的,这个暂时没有深究,个人理解应该是MTK的,因为原生aosp就不支持分区合并。

python out_sys/target/product/${CUSTOM_BUILD_SYSTEM_NAME}/images/split_build.py

--system-dir {ANDROID_SYSTEM_DIR}/out_sys/target/product/{CUSTOM_BUILD_SYSTEM_NAME}/images \

--vendor-dir {ANDROID_VENDOR_DIR}/out/target/product/{CUSTOM_PROJECT_NAME}/images \

--kernel-dir {ANDROID_VENDOR_DIR}/out/target/product/{CUSTOM_PROJECT_NAME}/images \

--output-dir ${ANDROID_MERGED_DIR} \

--otapackage

如上命令参数,同理--system-dir --vendor-dir kernel-dir指定编译出来的镜像,最后--output-dir目录指定输出路径,最关键的是--otapackage参数会做如下几步:

  • 重建完整的 target_files 目录结构:
  • --system-dir 解包或复制 SYSTEM/, PRODUCT/, SYSTEM_EXT/ 等目录
  • --vendor-dir 提取 VENDOR/, ODM/
  • --kernel-dir 获取 BOOT/, DTBO/, VBMETA/
  • 合并生成一个符合 AOSP 格式的 merged_target_files/ 目录
  • 生成**target_files.zip**
  • 调用 AOSP 工具生成 OTA 包:类似如下命令

build/tools/releasetools/ota_from_target_files.py \ --package_key ... \ --downgrade_allowed \ merged_target_files.zip \ $ {ANDROID_MERGED_DIR}/ota_update.zip

3、ota_from_target_files终极奥义

从如上可以对OTA包的编译生成进行如下总结:

  • AOSP标准方式:make otapackage/partialotapackage/otardppackage
  • 高通平台方式:build_image_standalone.py工具
  • MTK平台方式:split_build.py工具

最后都不约而同的执行了aosp提供的ota_from_target_files工具。

那么我们自己手动去做OTA包或者差分包的时候,是如何做的呢?其实也是通过ota_from_target_files工具进行生成:

步骤一:环境变量配置

AndroidS已以上的项目,首先确认下本地的java环境是否是java11即以上版本

如果本地低于java11 版本,请找该项目代码,从代码中设置java11 的临时环境:

cd androidu

export JAVA_HOME=`pwd`/prebuilts/jdk/jdk11/linux-x86

export PATH={JAVA_HOME}/bin:PATH

设置完后可以使用 java --version 确认下是否设置成功

步骤二:ota_from_target_files命令

使用编译后out目录下的 ota_from_target_files 文件制作不同的OTA包。

注意:因当前很多项目 vendor 和 system image是通过不同的代码来编译的,需要使用system image 编译的ota_from_target_files 文件

  • 编译差分包:

./androidu/out_sys/host/linux-x86/bin/ota_from_target_files -v

-k build/target/product/security//releasekey #指定应用签名key

-i merged_target_A.zip merged_target_B.zip #指定差分版本对应的target包

A_to_B_ota.zip #指定OTA输出文件名

  • 编译全包:

./androidu/out_sys/host/linux-x86/bin/ota_from_target_files -v

-k build/target/product/security//releasekey #指定应用签名key

merged_target_B.zip #指定全包版本对应的target包

B_ota.zip #指定OTA输出文件名

案例一:高通项目全包命令封装

bash 复制代码
CODE_PATH=${SCRIPT_PATH}
LA_UM_PATH=os/la.um
QSSI_PATH=os/la.qssi16
function build_full_ota()
{
	local project_codepath="${CODE_PATH}/${LA_UM_PATH}"
    local ota_toolpath="${project_codepath}/out/host/linux-x86/bin/"
	local releasekey_filename="${project_codepath}/build/target/product/security/"
	gotodir "${project_codepath}/out/dist/"
    echo "---------------------------------------------build_full_ota---------------------------------------------"
	${ota_toolpath}/ota_from_target_files -v -k ${releasekey_filename}/releasekey merged-qssi_64_lahaina612-target_files.zip merged-qssi_64_lahaina612-ota.zip
}
相关推荐
lxysbly37 分钟前
n64模拟器安卓版带金手指2026
android
游戏开发爱好者84 小时前
日常开发与测试的 App 测试方法、查看设备状态、实时日志、应用数据
android·ios·小程序·https·uni-app·iphone·webview
王码码20354 小时前
Flutter for OpenHarmony 实战之基础组件:第三十一篇 Chip 系列组件 — 灵活的标签化交互
android·flutter·交互·harmonyos
黑码哥4 小时前
ViewHolder设计模式深度剖析:iOS开发者掌握Android列表性能优化的实战指南
android·ios·性能优化·跨平台开发·viewholder
亓才孓4 小时前
[JDBC]元数据
android
独行soc4 小时前
2026年渗透测试面试题总结-17(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
金融RPA机器人丨实在智能4 小时前
Android Studio开发App项目进入AI深水区:实在智能Agent引领无代码交互革命
android·人工智能·ai·android studio
科技块儿4 小时前
利用IP查询在智慧城市交通信号系统中的应用探索
android·tcp/ip·智慧城市
独行soc5 小时前
2026年渗透测试面试题总结-18(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
王码码20355 小时前
Flutter for OpenHarmony 实战之基础组件:第二十七篇 BottomSheet — 动态底部弹窗与底部栏菜单
android·flutter·harmonyos