最近公司的一个老的项目,现在客户在专网方面遇到一点问题,进行版本升级时,由于客户是公安,比较强硬,要求升级时不能擦除数据,这个可以简单的通过改下打包脚本下参数就能解决。还是花了很长时间来跟踪OTA打包的过程,对深入了解还是有很大帮助。
### 相关变量184 PRODUCT_OUT := $(TARGET_PRODUCT_OUT_ROOT)/$(TARGET_DEVICE)
187
188 HOST_OUT_EXECUTABLES:= $(HOST_OUT)/bin ### HOST_OUT=\out\host\linux-x86\bin
189 HOST_OUT_SHARED_LIBRARIES:= $(HOST_OUT)/lib
190 HOST_OUT_JAVA_LIBRARIES:= $(HOST_OUT)/framework
191 HOST_OUT_SDK_ADDON := $(HOST_OUT)/sdk_addon
intermediates := $(call intermediates-dir-for,PACKAGING,target_files)
BUILT_TARGET_FILES := $(intermediates)/target.zip
BUILT_TARGET_FILES_PACKAGE := $(intermediates)/$(name).zip
$(BUILT_TARGET_FILES_PACKAGE): intermediates := $(intermediates)
$(BUILT_TARGET_FILES) $(BUILT_TARGET_FILES_PACKAGE): \
zip_root := $(intermediates)/$(name)
DEFAULT_SYSTEM_DEV_CERTIFICATE ##--->>build/target/product/security/testkey
ifeq ($(DEFAULT_SYSTEM_DEV_CERTIFICATE),build/target/product/security/testkey)
BUILD_KEYS := test-keys
else
BUILD_KEYS := release-keys
endif
# The dev key is used to sign this package, and as the key required
# for future OTA packages installed by this system. Actual product
# deliverables will be re-signed by hand. We expect this file to
# exist with the suffixes ".x509.pem" and ".pk8".
DEFAULT_KEY_CERT_PAIR := $(DEFAULT_SYSTEM_DEV_CERTIFICATE)
# -----------------------------------------------------------------
# Build a keystore with the authorized keys in it, used to verify the
# authenticity of downloaded OTA packages.
#
# This rule adds to ALL_DEFAULT_INSTALLED_MODULES, so it needs to come
# before the rules that use that variable to build the image.
ALL_DEFAULT_INSTALLED_MODULES += $(TARGET_OUT_ETC)/security/otacerts.zip
$(TARGET_OUT_ETC)/security/otacerts.zip: KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR)
$(TARGET_OUT_ETC)/security/otacerts.zip: $(addsuffix .x509.pem,$(DEFAULT_KEY_CERT_PAIR))
$(hide) rm -f $@
$(hide) mkdir -p $(dir $@)
$(hide) zip -qj $@ $<
.PHONY: otacerts
otacerts: $(TARGET_OUT_ETC)/security/otacerts.zip
# Keys authorized to sign OTA packages this build will accept. The
# build always uses dev-keys for this; release packaging tools will
# substitute other keys for this one.
OTA_PUBLIC_KEYS := $(DEFAULT_SYSTEM_DEV_CERTIFICATE).x509.pem
//签名
# Generate a file containing the keys that will be read by the
# recovery binary.
RECOVERY_INSTALL_OTA_KEYS := \
$(call intermediates-dir-for,PACKAGING,ota_keys)/keys
DUMPKEY_JAR := $(HOST_OUT_JAVA_LIBRARIES)/dumpkey.jar
$(RECOVERY_INSTALL_OTA_KEYS): PRIVATE_OTA_PUBLIC_KEYS := $(OTA_PUBLIC_KEYS)
$(RECOVERY_INSTALL_OTA_KEYS): extra_keys := $(patsubst %,%.x509.pem,$(PRODUCT_EXTRA_RECOVERY_KEYS))
$(RECOVERY_INSTALL_OTA_KEYS): $(OTA_PUBLIC_KEYS) $(DUMPKEY_JAR) $(extra_keys)
@echo "DumpPublicKey: $@ <= $(PRIVATE_OTA_PUBLIC_KEYS) $(extra_keys)"
@rm -rf $@
@mkdir -p $(dir $@)
java -jar $(DUMPKEY_JAR) $(PRIVATE_OTA_PUBLIC_KEYS) $(extra_keys) > $@
$(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) $(RECOVERYIMAGE_EXTRA_DEPS) \
$(INSTALLED_RAMDISK_TARGET) \
$(INSTALLED_BOOTIMAGE_TARGET) \
$(recovery_binary) \
$(recovery_initrc) $(recovery_kernel) \
$(INSTALLED_2NDBOOTLOADER_TARGET) \
$(recovery_build_prop) $(recovery_resource_deps) \
$(recovery_fstab) \
$(RECOVERY_INSTALL_OTA_KEYS)
编译OTA需要的工具
# -----------------------------------------------------------------
# host tools needed to build dist and OTA packages
DISTTOOLS := $(HOST_OUT_EXECUTABLES)/minigzip \
$(HOST_OUT_EXECUTABLES)/mkbootfs \
$(HOST_OUT_EXECUTABLES)/mkbootimg \
$(HOST_OUT_EXECUTABLES)/fs_config \
$(HOST_OUT_EXECUTABLES)/mkyaffs2image \
$(HOST_OUT_EXECUTABLES)/zipalign \
$(HOST_OUT_EXECUTABLES)/bsdiff \
$(HOST_OUT_EXECUTABLES)/imgdiff \
$(HOST_OUT_JAVA_LIBRARIES)/dumpkey.jar \
$(HOST_OUT_JAVA_LIBRARIES)/signapk.jar \
$(HOST_OUT_EXECUTABLES)/mkuserimg.sh \
$(HOST_OUT_EXECUTABLES)/make_ext4fs \
$(HOST_OUT_EXECUTABLES)/simg2img \
$(HOST_OUT_EXECUTABLES)/e2fsck
OTATOOLS := $(DISTTOOLS) \
$(HOST_OUT_EXECUTABLES)/aapt
.PHONY: otatools
otatools: $(OTATOOLS)
//生成的OTA的路径
# -----------------------------------------------------------------
# A zip of the directories that map to the target filesystem.
# This zip can be used to create an OTA package or filesystem image
# as a post-build step.
#
name := $(TARGET_PRODUCT)
ifeq ($(TARGET_BUILD_TYPE),debug)
name := $(name)_debug
endif
name := $(name)-target_files-$(FILE_NAME_TAG)
intermediates := $(call intermediates-dir-for,PACKAGING,target_files)
BUILT_TARGET_FILES := $(intermediates)/target.zip
BUILT_TARGET_FILES_PACKAGE := $(intermediates)/$(name).zip
$(BUILT_TARGET_FILES_PACKAGE): intermediates := $(intermediates)
$(BUILT_TARGET_FILES) $(BUILT_TARGET_FILES_PACKAGE): \
zip_root := $(intermediates)/$(name)
# Depending on the various images guarantees that the underlying
# directories are up-to-date.
$(BUILT_TARGET_FILES_PACKAGE): \
$(INSTALLED_BOOTIMAGE_TARGET) \
$(INSTALLED_RADIOIMAGE_TARGET) \
$(INSTALLED_RECOVERYIMAGE_TARGET) \
$(INSTALLED_SYSTEMIMAGE) \
$(INSTALLED_USERDATAIMAGE_TARGET) \
$(INSTALLED_CACHEIMAGE_TARGET) \
$(INSTALLED_VENDORIMAGE_TARGET) \
$(INSTALLED_ANDROID_INFO_TXT_TARGET) \
$(SELINUX_FC) \
$(built_ota_tools) \ ###
$(APKCERTS_FILE) \
$(HOST_OUT_EXECUTABLES)/fs_config \
$(HOST_OUT_EXECUTABLES)/checksparse.py \
$(HOST_OUT_EXECUTABLES)/rawprogram0.xml \
| $(ACP)
$(BUILT_TARGET_FILES) $(BUILT_TARGET_FILES_PACKAGE):
ifeq ($(TARGET_USERIMAGES_USE_EXT4),true)
@echo "unsparse the sparse ext4 image"
$(hide) python $(HOST_OUT_EXECUTABLES)/checksparse.py -i $(HOST_OUT_EXECUTABLES)/rawprogram0.xml -o $(PRODUCT_OUT)/sparse_images/rawprogram0_unsparse.xml -s $(PRODUCT_OUT) -t $(PRODUCT_OUT)/sparse_images
endif
//OTA 的工具集
built_ota_tools := \
$(call intermediates-dir-for,EXECUTABLES,applypatch)/applypatch \
$(call intermediates-dir-for,EXECUTABLES,applypatch_static)/applypatch_static \
$(call intermediates-dir-for,EXECUTABLES,check_prereq)/check_prereq \
$(call intermediates-dir-for,EXECUTABLES,sqlite3)/sqlite3 \
$(call intermediates-dir-for,EXECUTABLES,updater)/updater
ifneq ($(TARGET_FOTA_UPDATE_LIB),)
built_ota_tools += $(call intermediates-dir-for,EXECUTABLES,ipth_dua)/ipth_dua
endif
//OTA 打包名称
INTERNAL_OTA_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip
//默认的签名 , build/target/product/security/testkey 或是 release-keys
$(INTERNAL_OTA_PACKAGE_TARGET): KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR)
执行到这里才开始真正打包,可以看出是通过./build/tools/releasetools/ota_from_target_files的工具脚本进行打包的:
$(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(DISTTOOLS)
@echo "Package OTA: $@"
$(hide) ./build/tools/releasetools/ota_from_target_files -n -v -w \
-p $(HOST_OUT) \
-d $(device_type) \
-k $(KEY_CERT_PAIR) \
-f $(fota) \
$(BUILT_TARGET_FILES_PACKAGE) $@
.PHONY: otapackage
otapackage: $(INTERNAL_OTA_PACKAGE_TARGET)。
ota_from_target_files脚本的作用是以第一步生成的zip原始包作为输入,最终生成可用的OTA升级zip包。
用法---Usage: ota_from_target_files [flags] input_target_files output_ota_package
-b 过时的。
-k签名所使用的密钥
-i生成增量OTA包时使用此选项。后面我们会用到这个选项来生成OTA增量包。
-w是否清除userdata分区
-n在升级时是否不检查时间戳,缺省要检查,即缺省情况下只能基于旧版本升级。
-e是否有额外运行的脚本
-m执行过程中生成脚本(updater-script)所需要的格式,目前有两种即amend和edify。对应上两种版本升级时会采用不同的解释器。缺省会同时生成两种格式
的脚 本。
-p定义脚本用到的一些可执行文件的路径。
-s定义额外运行脚本的路径。
-x定义额外运行的脚本可能用的键值对。
-v执行过程中打印出执行的命令。
-h命令帮助
其中-w参数可配置升级时是否擦除用户已经使用的数据,如安装的app,内置存储的文件等等。大多数厂商都加有这个参数,安装时擦除数据即wipe data.
文档说明如下:
Usage: ota_from_target_files [flags] input_target_files output_ota_package
-b (--board_config) <file>
Deprecated.
-k (--package_key) <key> Key to use to sign the package (default is
the value of default_system_dev_certificate from the input
target-files's META/misc_info.txt, or
"build/target/product/security/testkey" if that value is not
specified).
For incremental OTAs, the default value is based on the source
target-file, not the target build.
-i (--incremental_from) <file>
Generate an incremental OTA using the given target-files zip as
the starting build.
-w (--wipe_user_data)
Generate an OTA package that will wipe the user data partition
when installed.
-n (--no_prereq)
Omit the timestamp prereq check normally included at the top of
the build scripts (used for developer OTA packages which
legitimately need to go back and forth).
-e (--extra_script) <file>
Insert the contents of file at the end of the update script.
-a (--aslr_mode) <on|off>
Specify whether to turn on ASLR for the package (on by default).
-d (--device_type) <type>
Specify MMC or MTD type device. MTD by default
-f (--fota) <fota>
Specify if fota upgrade is used or not. not used by default
"""
进入ota_from_target_files:
进入脚本函数后:
main(sys.argv[1:])
打完整包 WriteFullOTAPackage(input_zip, output_zip, OPTIONS.fota):
f OPTIONS.incremental_source is None:
WriteFullOTAPackage(input_zip, output_zip, OPTIONS.fota)
if OPTIONS.package_key is None:
签名包信息配置,会对签名的输入文件进行签名信息校验
OPTIONS.package_key = OPTIONS.info_dict.get(
"default_system_dev_certificate",
"build/target/product/security/testkey")
else:
打增量包:
print "unzipping source target-files..."
OPTIONS.source_tmp, source_zip = common.UnzipTemp(OPTIONS.incremental_source)
OPTIONS.target_info_dict = OPTIONS.info_dict
OPTIONS.source_info_dict = common.LoadInfoDict(source_zip, OPTIONS.device_type)
if OPTIONS.package_key is None:
OPTIONS.package_key = OPTIONS.source_info_dict.get(
"default_system_dev_certificate",
"build/target/product/security/testkey")
WriteIncrementalOTAPackage(input_zip, source_zip, output_zip, OPTIONS.fota)
打包中都有进度提示,如
script.ShowProgress(0.5, 0)
如果OPTIONS.wipe_user_data为true,则擦除数据:
if OPTIONS.wipe_user_data:
script.FormatPartition("/data")
if "selinux_fc" in OPTIONS.info_dict:
WritePolicyConfig(OPTIONS.info_dict["selinux_fc"], output_zip)
script.FormatPartition("/system")
script.Mount("/system")
script.UnpackPackageDir("recovery", "/system")
script.UnpackPackageDir("system", "/system")