转载
概要:
此篇文章主要介绍 Android ota 包(Android L)的编译制作过程,侧重于 Makefile 中编译 ota 的流程,从指定 target 到编译 cmd 等流程。
主要流程:
源码分析:
build/core/Makefile:
.PHONY: otapackage
otapackage: $(INTERNAL_OTA_PACKAGE_TARGET)
otapackage 伪命令,即执行 make otapackage
时,将编译$(INTERNAL_OTA_PACKAGE_TARGET)
目标
$(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(DISTTOOLS)
@echo "Package OTA: $@"
ifneq ($(TARGET_USERIMAGES_USE_UBIFS),true)
ifeq (yes, $(filter $(TRUSTONIC_TEE_SUPPORT) $(MTK_ATF_SUPPORT),yes))
$(hide) MTK_SECURITY_SW_SUPPORT=$(MTK_SECURITY_SW_SUPPORT) MKBOOTIMG=$(MKBOOTIMG) \
./build/tools/releasetools/ota_from_target_files -v \
--block \
-p $(HOST_OUT) \
-k $(KEY_CERT_PAIR) \
-z $(PRODUCT_OUT)/trustzone.bin \
$(if $(OEM_OTA_CONFIG), -o $(OEM_OTA_CONFIG)) \
$(BUILT_TARGET_FILES_PACKAGE) $@
else
$(hide) MTK_SECURITY_SW_SUPPORT=$(MTK_SECURITY_SW_SUPPORT) MKBOOTIMG=$(MKBOOTIMG) \
./build/tools/releasetools/ota_from_target_files -v \
--block \
-p $(HOST_OUT) \
-k $(KEY_CERT_PAIR) \
$(if $(OEM_OTA_CONFIG), -o $(OEM_OTA_CONFIG)) \
$(BUILT_TARGET_FILES_PACKAGE) $@
endif
else
$(hide) MTK_SECURITY_SW_SUPPORT=$(MTK_SECURITY_SW_SUPPORT) ./build/tools/releasetools/ota_from_target_files -v \
-n \
-g \
-p $(HOST_OUT) \
-k $(KEY_CERT_PAIR) \
$(BUILT_TARGET_FILES_PACKAGE) $@
endif
ifeq ($(strip $(MTK_FW_UPGRADE)), yes)
# @echo "Package FWUpgradePackage"
# bash $(FWUPGRADEPACKAGE_SH) $(PRODUCT_OUT) $(KEY_CERT_PAIR)
endif
依赖两部分:
$(BUILT_TARGET_FILES_PACKAGE)$(DISTTOOLS)
然后先找$(BUILT_TARGET_FILES_PACKAGE)
。BUILT_TARGET_FILES_PACKAGE:= (intermediates)/(intermediates)/(intermediates)/(name).zip
实际为:full_p92s_hd-target_files-eng.wan.zip
# -----------------------------------------------------------------
# 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)
以上这些步骤主要确定 name 变量名称 name:=(project−name)−targetfiles−(project-name)-target_files-(project−name)−targetfiles−(FILE_NAME_TAG)
,假设 project-name=p92 FILE_NAME_TAG=eng
, 则:
name := p92-target_files-eng
intermediates := $(call intermediates-dir-for,PACKAGING,target_files)
此处调用了一个函数:intermediates-dir-for
,我们来解读一下它的定义,就知道这句话的意思了。它定义在build/core/definitions.mk
中,如下:
$(1): target class, like "APPS"
$(2): target name, like "NotePad"
$(3): if non-empty, this is a HOST target.
$(4): if non-empty, force the intermediates to be COMMON
$(5): if non-empty, force the intermedistes to be for the 2ndarch
define intermediates-dir-for
$(strip \
$(eval _idfClass :=$(strip $(1))) \
$(if $(_idfClass),, \
$(error$(LOCAL_PATH): Class not defined in call to intermediates-dir-for)) \
$(eval _idfName :=$(strip $(2))) \
$(if $(_idfName),, \
$(error$(LOCAL_PATH): Name not defined in call to intermediates-dir-for)) \
$(eval _idfPrefix :=$(if $(strip $(3)),HOST,TARGET)) \
$(eval_idf2ndArchPrefix := $(if $(strip $(5)),$(TARGET_2ND_ARCH_VAR_PREFIX))) \
$(if $(filter$(_idfPrefix)-$(_idfClass),$(COMMON_MODULE_CLASSES))$(4), \
$(eval _idfIntBase:= $($(_idfPrefix)_OUT_COMMON_INTERMEDIATES)) \
,$(if $(filter$(_idfClass),SHARED_LIBRARIES STATIC_LIBRARIES EXECUTABLES GYP),\
$(eval_idfIntBase := $($(_idf2ndArchPrefix)$(_idfPrefix)_OUT_INTERMEDIATES)) \
,$(eval _idfIntBase:= $($(_idfPrefix)_OUT_INTERMEDIATES)) \
) \
) \
$(_idfIntBase)/$(_idfClass)/$(_idfName)_intermediates \
)
endif
传入的参数:$1= PACKAGING
, $2=target-files
, $3
及以后的参数为空。
所以执行下来:
- _idfClass := PACKAGING
- _idfName := target_files
- _idfPrefix := TARGET (以为$3为空,所以if函数走到else part 为TARGET)
- _idfIntBase := TARGET_OUT_INTERMEDIATES
由于这个宏在 build/core/envsetup.mk
中有定义:
TARGET_OUT_INTERMEDIATES := (PRODUCTOUT)/obj(out/target/product/(PRODUCT_OUT)/obj (out/target/product/(PRODUCTOUT)/obj(out/target/product/(project)/obj)
执行结果:
out/target/product/$(project)/obj/PACKAGING/target_files_intermediates
所以这个函数调用之后:intermediates := out/target/product/$(project)/obj/PACKAGING/target-files_intermeidates
BUILT_TARGET_FILES_PACKAGE := $(intermediates)/$(name).zip
$(BUILT_TARGET_FILES_PACKAGE): intermediates := $(intermediates)
$(BUILT_TARGET_FILES_PACKAGE): \
zip_root := $(intermediates)/$(name)
以上几句同样是对目标等变量赋值:
BUILT_TARGET_FILES_PACKAGE := out/target/product/$(project)/obj/PACKAGING/target-files_intermeidates/p92-target_files-eng.zip
(这个即是将要生成的目标文件)
然后设定两个目标指定变量:intermediates
和zip_root
,即这两个变量只在 BUILT_TARGET_FILES_PACKAGE
这个目标上下文有效(类似于C语言的局部变量)Intermediates:= out/target/product/$(project)/obj/PACKAGING/target-files_intermeidates
zip_root := out/target/product/$(project)/obj/PACKAGING/target-files_intermeidates/p92-target_files-eng
# $(1): Directory to copy
# $(2): Location to copy it to
# The "ls -A" is to prevent "acp s/* d" from failing if s is empty.
define package_files-copy-root
if [ -d "$(strip $(1))" -a "$$(ls -A $(1))" ]; then \
mkdir -p $(2) && \
$(ACP) -rd $(strip $(1))/* $(2); \
fi
endef
以上定义了一个 copy 文件的函数,有两个参数 $1,$2,把 $1 中的内容拷到 $2 中。
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
ifeq ($(TARGET_ARCH),arm64)
built_ota_tools += $(call intermediates-dir-for,EXECUTABLES,updater,,,t)/updater
else
built_ota_tools += $(call intermediates-dir-for,EXECUTABLES,updater)/updater
endif
以上主要做两件事情:
- 把
applypatch … sqlite3
等可执行文件(obj/EXECUTABLES/…目录下)赋值给built_ota_tools
把
updater
可执行文件追加赋值给built_ota_tools
。这里值得注意的是updater
的调用参数:(EXECUTABLES,updater,,,t)
,存在 $5 ,结合上文对intermediates-dir-for
函数分析可得到:$(eval_idfIntBase := ((((_idf2ndArchPrefix)$(_idfPrefix)_OUT_INTERMEDIATES)) 可得到:idfIntBase :=$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATES:= $(PRODUCT_OUT)/obj_$(TARGET_2ND_ARCH) :=out/target/product/$(project)/obj_arm
所以最后返回:out/target/product/$(project)/obj_arm/updater_intermediates/(updater)
可发现调用intermediates-dir-for
此函数,如果存在参数 $5,并且 _idfClass
在 SHARED_LIBRARIES STATIC_LIBRARIES EXECUTABLES GYP
中,则 idfIntBase := out/target/product/$(project)/obj_arm
(而非obj)。最终 built_ota_tools := applypatchapplypatch_static check_prereq sqlite3 updater
这几支文件(目录忽略)
$(BUILT_TARGET_FILES_PACKAGE): PRIVATE_OTA_TOOLS := $(built_ota_tools)
$(BUILT_TARGET_FILES_PACKAGE): PRIVATE_RECOVERY_API_VERSION := $(RECOVERY_API_VERSION)
$(BUILT_TARGET_FILES_PACKAGE): PRIVATE_RECOVERY_FSTAB_VERSION := $(RECOVERY_FSTAB_VERSION)
ifeq ($(TARGET_RELEASETOOLS_EXTENSIONS),)
# default to common dir for device vendor
$(BUILT_TARGET_FILES_PACKAGE): tool_extensions := $(TARGET_DEVICE_DIR)/../common
else
$(BUILT_TARGET_FILES_PACKAGE): tool_extensions := $(TARGET_RELEASETOOLS_EXTENSIONS)
endif
- 把
built_ota_tools
赋值给目标制定变量PRIVATE_OTA_TOOLS
分别对
PRIVATE_RECOVERY_API_VERSION
,PRIVATE_RECOVERY_FSTAB_VERSION
赋值,其中RECOVERY_API_VERSION
,RECOVERY_FSTAB_VERSION
这两个变量在bootable/recovery/Android.mk
中有定义:RECOVERY_API_VERSION:= 3 RECOVERY_FSTAB_VERSION:= 2
- 对
tool_extensions
赋值
# 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 \
| $(ACP)
为目标添(out/…/obj/PACKAGING/ target-files_intermeidates/p92-target_files-eng.zip
)加依赖,分为两种依赖,“|”前为普通依赖,即这些依赖 INSTALLED_BOOTIMAGE_TARGET
发生改变,maketarget
时目标也要重新构建;“|”后为 order-only
依赖,表示 ACP 这个变量若发生改变,而 target 已经存在时则不需要被重建,若第一次生成则需要重建。
ifeq ($(TARGET_USERIMAGES_USE_EXT4),true)
$(BUILT_TARGET_FILES_PACKAGE): $(INSTALLED_CACHEIMAGE_TARGET)
Endif
继续添加依赖 $(INSTALLED_CACHEIMAGE_TARGET)
@echo "Package target files: $@"
$(hide) rm -rf $@ $(zip_root)
$(hide) mkdir -p $(dir $@) $(zip_root)
@# Components of the recovery image
$(hide) mkdir -p $(zip_root)/RECOVERY
$(hide) $(call package_files-copy-root, \
$(TARGET_RECOVERY_ROOT_OUT),$(zip_root)/RECOVERY/RAMDISK)
ifdef INSTALLED_KERNEL_TARGET
$(hide) $(ACP) $(INSTALLED_KERNEL_TARGET) $(zip_root)/RECOVERY/kernel
$(hide) $(ACP) $(recovery_ramdisk) $(zip_root)/RECOVERY/ramdisk
ifeq ($(MTK_HEADER_SUPPORT),yes)
$(hide) $(ACP) $(recovery_ramdisk_bthdr) $(zip_root)/RECOVERY/ramdisk-bthdr
endif
endif
ifdef INSTALLED_2NDBOOTLOADER_TARGET
$(hide) $(ACP) \
$(INSTALLED_2NDBOOTLOADER_TARGET) $(zip_root)/RECOVERY/second
endif
ifdef BOARD_KERNEL_CMDLINE
$(hide) echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/RECOVERY/cmdline
endif
ifdef BOARD_KERNEL_BASE
$(hide) echo "$(BOARD_KERNEL_BASE)" > $(zip_root)/RECOVERY/base
endif
ifdef BOARD_KERNEL_PAGESIZE
$(hide) echo "$(BOARD_KERNEL_PAGESIZE)" > $(zip_root)/RECOVERY/pagesize
endif
ifdef BOARD_RAMDISK_OFFSET
$(hide) echo "$(BOARD_RAMDISK_OFFSET)" > $(zip_root)/RECOVERY/ramdisk_offset
endif
ifdef BOARD_KERNEL_OFFSET
$(hide) echo "$(BOARD_KERNEL_OFFSET)" > $(zip_root)/RECOVERY/kernel_offset
endif
ifdef BOARD_TAGS_OFFSET
$(hide) echo "$(BOARD_TAGS_OFFSET)" > $(zip_root)/RECOVERY/tags_offset
endif
$(hide) if [ -f $(PRODUCT_OUT)/custom_build_verno ]; then \
cat $(PRODUCT_OUT)/custom_build_verno > $(zip_root)/RECOVERY/board; \
fi
@# Components of the boot image
$(hide) mkdir -p $(zip_root)/BOOT
$(hide) $(call package_files-copy-root, \
$(TARGET_ROOT_OUT),$(zip_root)/BOOT/RAMDISK)
ifdef INSTALLED_KERNEL_TARGET
$(hide) $(ACP) $(INSTALLED_KERNEL_TARGET) $(zip_root)/BOOT/kernel
$(hide) $(ACP) $(INSTALLED_RAMDISK_TARGET) $(zip_root)/BOOT/ramdisk
endif
ifdef INSTALLED_2NDBOOTLOADER_TARGET
$(hide) $(ACP) \
$(INSTALLED_2NDBOOTLOADER_TARGET) $(zip_root)/BOOT/second
endif
ifdef BOARD_KERNEL_CMDLINE
$(hide) echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/BOOT/cmdline
endif
ifdef BOARD_KERNEL_BASE
$(hide) echo "$(BOARD_KERNEL_BASE)" > $(zip_root)/BOOT/base
endif
ifdef BOARD_RAMDISK_OFFSET
$(hide) echo "$(BOARD_RAMDISK_OFFSET)" > $(zip_root)/BOOT/ramdisk_offset
endif
ifdef BOARD_KERNEL_OFFSET
$(hide) echo "$(BOARD_KERNEL_OFFSET)" > $(zip_root)/BOOT/kernel_offset
endif
ifdef BOARD_TAGS_OFFSET
$(hide) echo "$(BOARD_TAGS_OFFSET)" > $(zip_root)/BOOT/tags_offset
endif
ifdef BOARD_KERNEL_PAGESIZE
$(hide) echo "$(BOARD_KERNEL_PAGESIZE)" > $(zip_root)/BOOT/pagesize
endif
$(hide) if [ -f $(PRODUCT_OUT)/custom_build_verno ]; then \
cat $(PRODUCT_OUT)/custom_build_verno > $(zip_root)/BOOT/board; \
fi
$(hide) $(foreach t,$(INSTALLED_RADIOIMAGE_TARGET),\
mkdir -p $(zip_root)/RADIO; \
$(ACP) $(t) $(zip_root)/RADIO/$(notdir $(t));)
@# Contents of the system image
$(hide) $(call package_files-copy-root, \
$(SYSTEMIMAGE_SOURCE_DIR),$(zip_root)/SYSTEM)
@# Contents of the data image
$(hide) $(call package_files-copy-root, \
$(TARGET_OUT_DATA),$(zip_root)/DATA)
@# Contents of the apd image
$(hide) $(call package_files-copy-root, \
$(TARGET_OUT_APD),$(zip_root)/APD)
ifdef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
@# Contents of the vendor image
$(hide) $(call package_files-copy-root, \
$(TARGET_OUT_VENDOR),$(zip_root)/VENDOR)
endif
#wschen 2012-11-07
$(if $(BOARD_CUSTOMIMAGE_PARTITION_SIZE), \
$(hide) $(call package_files-copy-root, \
$(TARGET_CUSTOM_OUT),$(zip_root)/CUSTOM))
@# Extra contents of the OTA package
$(hide) mkdir -p $(zip_root)/OTA/bin
$(hide) $(ACP) $(INSTALLED_ANDROID_INFO_TXT_TARGET) $(zip_root)/OTA/
$(hide) $(ACP) $(PRIVATE_OTA_TOOLS) $(zip_root)/OTA/bin/
上面内容主要是在 zip_root
目录下创建相应升级分区需要的目录,并把 out
目录下对应的文件 copy
到相应目录下。如果需要添加一个新分区到 ota 中,则需要在上面做一些修改,可参考 apd 分区。
@# Security information of the OTA package
@echo "[SEC OTA] Adding Security information to OTA package"
@echo "[SEC OTA] path : vendor/mediatek/proprietary/custom/$(MTK_BASE_PROJECT)/security/recovery/SEC_VER.txt"
$(hide) $(ACP) vendor/mediatek/proprietary/custom/$(MTK_BASE_PROJECT)/security/recovery/SEC_VER.txt $(zip_root)/OTA/
-$(hide) $(ACP) $(PRODUCT_OUT)/trustzone.bin $(zip_root)/OTA/
@# Files that do not end up in any images, but are necessary to
@# build them.
$(hide) mkdir -p $(zip_root)/META
$(hide) $(ACP) $(APKCERTS_FILE) $(zip_root)/META/apkcerts.txt
$(hide) if test -e $(tool_extensions)/releasetools.py; then $(ACP) $(tool_extensions)/releasetools.py $(zip_root)/META/; fi
$(hide) echo "$(PRODUCT_OTA_PUBLIC_KEYS)" > $(zip_root)/META/otakeys.txt
$(hide) echo "recovery_api_version=$(PRIVATE_RECOVERY_API_VERSION)" > $(zip_root)/META/misc_info.txt
$(hide) echo "fstab_version=$(PRIVATE_RECOVERY_FSTAB_VERSION)" >> $(zip_root)/META/misc_info.txt
fdef BOARD_FLASH_BLOCK_SIZE
$(hide) echo "blocksize=$(BOARD_FLASH_BLOCK_SIZE)" >> $(zip_root)/META/misc_info.txt
endif
ifdef BOARD_BOOTIMAGE_PARTITION_SIZE
$(hide) echo "boot_size=$(BOARD_BOOTIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt
endif
ifdef BOARD_RECOVERYIMAGE_PARTITION_SIZE
$(hide) echo "recovery_size=$(BOARD_RECOVERYIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt
endif
ifdef TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS
@# TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS can be empty to indicate that nothing but defaults should be used.
$(hide) echo "recovery_mount_options=$(TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS)" >> $(zip_root)/META/misc_info.txt
else
$(hide) echo "recovery_mount_options=$(DEFAULT_TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS)" >> $(zip_root)/META/misc_info.txt
endif
$(hide) echo "tool_extensions=$(tool_extensions)" >> $(zip_root)/META/misc_info.txt
$(hide) echo "default_system_dev_certificate=$(DEFAULT_KEY_CERT_PAIR)" >> $(zip_root)/META/misc_info.txt
ifdef PRODUCT_EXTRA_RECOVERY_KEYS
$(hide) echo "extra_recovery_keys=$(PRODUCT_EXTRA_RECOVERY_KEYS)" >> $(zip_root)/META/misc_info.txt
endif
$(hide) echo 'mkbootimg_args=$(BOARD_MKBOOTIMG_ARGS)' >> $(zip_root)/META/misc_info.txt
$(hide) echo "use_set_metadata=1" >> $(zip_root)/META/misc_info.txt
$(hide) echo "multistage_support=1" >> $(zip_root)/META/misc_info.txt
$(hide) echo "update_rename_support=1" >> $(zip_root)/META/misc_info.txt
$(hide) echo "blockimgdiff_versions=1,2" >> $(zip_root)/META/misc_info.txt
ifeq ($(MTK_HEADER_SUPPORT),yes)
$(hide) echo "mtk_header_support=1" >> $(zip_root)/META/misc_info.txt
endif
ifneq ($(OEM_THUMBPRINT_PROPERTIES),)
# OTA scripts are only interested in fingerprint related properties
$(hide) echo "oem_fingerprint_properties=$(OEM_THUMBPRINT_PROPERTIES)" >> $(zip_root)/META/misc_info.txt
endif
ifeq ($(TARGET_USERIMAGES_USE_UBIFS),true)
$(call generate-ubifs-prop-dictionary, $(zip_root)/META/misc_info.txt)
endif
$(call generate-userimage-prop-dictionary, $(zip_root)/META/misc_info.txt)
ifeq ($(TRUSTONIC_TEE_SUPPORT),yes)
$(hide) ./build/tools/releasetools/make_recovery_patch $(zip_root) $(zip_root) $(PRODUCT_OUT)
else
$(hide) ./build/tools/releasetools/make_recovery_patch $(zip_root) $(zip_root) $(TRUSTONIC_TEE_SUPPORT)
endif
ifeq ($(strip $(MTK_SECURITY_SW_SUPPORT)), yes)
#security boot signature
$(hide) $(SHELL) $(SECURITY_SIG_TOOL)
$(hide) cp $(PRODUCT_OUT)/sig/boot.sig $(zip_root)/META/
$(hide) cp $(PRODUCT_OUT)/sig/recovery.sig $(zip_root)/META/
$(hide) cp $(PRODUCT_OUT)/sig/recovery.sig $(zip_root)/SYSTEM/etc/
Endif
继续做一些 copy 文件的动作。
@# Zip everything up, preserving symlinks
$(hide) (cd $(zip_root) && zip -qry ../$(notdir $@) .)
@# Run fs_config on all the system, vendor, boot ramdisk,
@# and recovery ramdisk files in the zip, and save the output
把 zip_root 中的内容压缩成目标压缩包 zip –qry …/p92-target_files-eng.zip
。
$(hide) zipinfo -1 $@ | awk 'BEGIN { FS="SYSTEM/" } /^SYSTEM\// {print "system/" $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -S $(SELINUX_FC) > $(zip_root)/META/filesystem_config.txt
$(hide) zipinfo -1 $@ | awk 'BEGIN { FS="VENDOR/" } /^VENDOR\// {print "vendor/" $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -S $(SELINUX_FC) > $(zip_root)/META/vendor_filesystem_config.txt
$(hide) zipinfo -1 $@ | awk 'BEGIN { FS="APD/" } /^APD\// {print "apd/" $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -S $(SELINUX_FC) > $(zip_root)/META/apd_filesystem_config.txt
$(hide) zipinfo -1 $@ | awk 'BEGIN { FS="BOOT/RAMDISK/" } /^BOOT\/RAMDISK\// {print $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -S $(SELINUX_FC) > $(zip_root)/META/boot_filesystem_config.txt
$(hide) zipinfo -1 $@ | awk 'BEGIN { FS="RECOVERY/RAMDISK/" } /^RECOVERY\/RAMDISK\// {print $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -S $(SELINUX_FC) > $(zip_root)/META/recovery_filesystem_config.txt
#wschen 2012-11-07
$(if $(BOARD_CUSTOMIMAGE_PARTITION_SIZE), \
$(hide) zipinfo -1 $@ | awk 'BEGIN { FS="CUSTOM/" } /^CUSTOM\// {print "custom/" $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -S $(SELINUX_FC) > $(zip_root)/META/custom_filesystem_config.txt)
为需要ota升级的分区目录及其目录下的文件添加selinux权限,并把这些权限内容输出到X_filesystem_config.txt
文件中,如meta/apd_filesystem_config.txt
:
apd 0 0 755selabel=u:object_r:apd_file:s0 capabilities=0x0
apd/test.ini 0 2000 777selabel=u:object_r:apd_file:s0 capabilities=0x0
apd/apd.txt 0 2000 777selabel=u:object_r:apd_file:s0 capabilities=0x0
apd/apd.ini 0 2000 777selabel=u:object_r:apd_file:s0 capabilities=0x0
$(hide) (cd $(zip_root) && zip -q ../$(notdir $@) META/*filesystem_config.txt)
把这些 *filesystem_config.txt
文件一并放置目标压缩包中
$(hide) ./build/tools/releasetools/add_img_to_target_files -p $(HOST_OUT) $@
这个文件 add_img_to_target_files.py
很重要,主要功能是生成一个 images 文件夹,存放着生成的各种 img(包括需要添加至 ota 升级的分区),如下图。如果需要把一个新分区添加至 ota 升级包中,这个文件则需要修改,可参考 custom/vendor 分区的添加方法。
$(hide) ./build/tools/releasetools/replace_img_from_target_files.py $@ $(PRODUCT_OUT)
要了解这句话的主要目的,来看一下 replace_img_from_target_files.py
文件的注解:
'''
Given a target-files zipfilethat does contain images (ie, does
have an IMAGES/ top-level subdirectory), replace the images to
the output dir.
Usage: replace_img_from_target_files target_files output
'''
把目标压缩包 out/target/product/(project)/obj/PACKAGING/target−filesintermeidates/p92−targetfiles−eng.zip
中的images/
路径下的各个 img 输出到 out/target/product/(project)/obj/PACKAGING/target-files_intermeidates/p92-target_files-eng.zip
中的 images/
路径下的各个 img 输出到 out/target/product/(project)/obj/PACKAGING/target−filesintermeidates/p92−targetfiles−eng.zip
中的 images/
路径下的各个 img 输出到 out/target/product/(project-name)/
目录下。比如替换 out… 目录下原来的 boot.img,system.img,apd.img 等。
然后来看一下另外一个依赖:
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 \
$(HOST_OUT_EXECUTABLES)/build_verity_tree \
$(HOST_OUT_EXECUTABLES)/verity_signer \
$(HOST_OUT_EXECUTABLES)/append2simg
其实就是定义 disttools
为 out/host/
目录下的一些可执行文件。
最后再跳到终极目标的 cmd 开始执行:
$(hide) MTK_SECURITY_SW_SUPPORT=$(MTK_SECURITY_SW_SUPPORT) MKBOOTIMG=$(MKBOOTIMG) \
./build/tools/releasetools/ota_from_target_files -v \
--block \
-p $(HOST_OUT) \
-k $(KEY_CERT_PAIR) \
$(if $(OEM_OTA_CONFIG), -o $(OEM_OTA_CONFIG)) \
$(BUILT_TARGET_FILES_PACKAGE) $@
所以跳到 ota_from_target_files python
文件中,接下来就要看 ota_from_target_files
这个文件的作用了。