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
}
相关推荐
2501_9159090616 小时前
苹果iOS应用上架详细流程与注意事项解析
android·ios·小程序·https·uni-app·iphone·webview
AC赳赳老秦16 小时前
跨境科技服务的基石:DeepSeek赋能多语言技术文档与合规性说明的深度实践
android·大数据·数据库·人工智能·科技·deepseek·跨境
晚霞的不甘17 小时前
解决 Flutter for OpenHarmony 构建失败:HVigor ERROR 00303168 (SDK component missing)
android·javascript·flutter
2501_9445215917 小时前
Flutter for OpenHarmony 微动漫App实战:分享功能实现
android·开发语言·javascript·flutter·ecmascript
kekegdsz17 小时前
Android构建优化:编译速度从 10 分钟编译到 10 秒
android·性能优化·gradle
2501_9445215918 小时前
Flutter for OpenHarmony 微动漫App实战:标签筛选功能实现
android·开发语言·前端·javascript·flutter
mjhcsp18 小时前
如何做一个网站?
android
2501_9159090618 小时前
在无需越狱的前提下如何对 iOS 设备进行文件管理与数据导出
android·macos·ios·小程序·uni-app·cocoa·iphone
_F_y18 小时前
MySQL表的增删查改
android·数据库·mysql