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
}
相关推荐
千里马学框架3 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台3 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone3 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc3 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo3 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077003 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone3 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen3 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone3 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui