转载

概要:

此篇文章次要介绍 Android ota 包(Android L)的编译制作过程,侧重于 Makefile 中编译 ota 的流程,从指定 target 到编译 cmd 等流程。

次要流程:

源码剖析:

build/core/Makefile:

.PHONY: otapackageotapackage: $(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) $@  endifelse    $(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) $@endififeq ($(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)_debugendifname := $(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-engintermediates := $(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 2ndarchdefine 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 (这个即是将要生成的指标文件)

而后设定两个指标指定变量:intermediateszip_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); \  fiendef

以上定义了一个 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)/sqlite3ifeq ($(TARGET_ARCH),arm64)  built_ota_tools += $(call intermediates-dir-for,EXECUTABLES,updater,,,t)/updaterelse  built_ota_tools += $(call intermediates-dir-for,EXECUTABLES,updater)/updaterendif

以上次要做两件事件:

  1. applypatch … sqlite3 等可执行文件(obj/EXECUTABLES/…目录下)赋值给 built_ota_tools
  2. 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,并且 _idfClassSHARED_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)/../commonelse$(BUILT_TARGET_FILES_PACKAGE): tool_extensions := $(TARGET_RELEASETOOLS_EXTENSIONS)endif
  1. built_ota_tools 赋值给指标制订变量 PRIVATE_OTA_TOOLS
  2. 别离对 PRIVATE_RECOVERY_API_VERSION, PRIVATE_RECOVERY_FSTAB_VERSION 赋值,其中 RECOVERY_API_VERSION , RECOVERY_FSTAB_VERSION 这两个变量在 bootable/recovery/Android.mk 中有定义:

    RECOVERY_API_VERSION:= 3RECOVERY_FSTAB_VERSION:= 2
  3. 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/ramdiskifeq ($(MTK_HEADER_SUPPORT),yes)    $(hide) $(ACP) $(recovery_ramdisk_bthdr) $(zip_root)/RECOVERY/ramdisk-bthdrendifendififdef INSTALLED_2NDBOOTLOADER_TARGET    $(hide) $(ACP) \        $(INSTALLED_2NDBOOTLOADER_TARGET) $(zip_root)/RECOVERY/secondendififdef BOARD_KERNEL_CMDLINE    $(hide) echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/RECOVERY/cmdlineendififdef BOARD_KERNEL_BASE    $(hide) echo "$(BOARD_KERNEL_BASE)" > $(zip_root)/RECOVERY/baseendififdef BOARD_KERNEL_PAGESIZE    $(hide) echo "$(BOARD_KERNEL_PAGESIZE)" > $(zip_root)/RECOVERY/pagesizeendififdef BOARD_RAMDISK_OFFSET    $(hide) echo "$(BOARD_RAMDISK_OFFSET)" > $(zip_root)/RECOVERY/ramdisk_offsetendififdef BOARD_KERNEL_OFFSET    $(hide) echo "$(BOARD_KERNEL_OFFSET)" > $(zip_root)/RECOVERY/kernel_offsetendififdef BOARD_TAGS_OFFSET    $(hide) echo "$(BOARD_TAGS_OFFSET)" > $(zip_root)/RECOVERY/tags_offsetendif    $(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/ramdiskendififdef INSTALLED_2NDBOOTLOADER_TARGET    $(hide) $(ACP) \        $(INSTALLED_2NDBOOTLOADER_TARGET) $(zip_root)/BOOT/secondendififdef BOARD_KERNEL_CMDLINE    $(hide) echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/BOOT/cmdlineendififdef BOARD_KERNEL_BASE    $(hide) echo "$(BOARD_KERNEL_BASE)" > $(zip_root)/BOOT/baseendififdef BOARD_RAMDISK_OFFSET    $(hide) echo "$(BOARD_RAMDISK_OFFSET)" > $(zip_root)/BOOT/ramdisk_offsetendififdef BOARD_KERNEL_OFFSET    $(hide) echo "$(BOARD_KERNEL_OFFSET)" > $(zip_root)/BOOT/kernel_offsetendififdef BOARD_TAGS_OFFSET    $(hide) echo "$(BOARD_TAGS_OFFSET)" > $(zip_root)/BOOT/tags_offsetendififdef BOARD_KERNEL_PAGESIZE    $(hide) echo "$(BOARD_KERNEL_PAGESIZE)" > $(zip_root)/BOOT/pagesizeendif    $(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.txtfdef BOARD_FLASH_BLOCK_SIZE    $(hide) echo "blocksize=$(BOARD_FLASH_BLOCK_SIZE)" >> $(zip_root)/META/misc_info.txtendififdef BOARD_BOOTIMAGE_PARTITION_SIZE    $(hide) echo "boot_size=$(BOARD_BOOTIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txtendififdef BOARD_RECOVERYIMAGE_PARTITION_SIZE    $(hide) echo "recovery_size=$(BOARD_RECOVERYIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txtendififdef 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.txtelse    $(hide) echo "recovery_mount_options=$(DEFAULT_TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS)" >> $(zip_root)/META/misc_info.txtendif    $(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.txtifdef PRODUCT_EXTRA_RECOVERY_KEYS    $(hide) echo "extra_recovery_keys=$(PRODUCT_EXTRA_RECOVERY_KEYS)" >> $(zip_root)/META/misc_info.txtendif    $(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.txtifeq ($(MTK_HEADER_SUPPORT),yes)    $(hide) echo "mtk_header_support=1" >> $(zip_root)/META/misc_info.txtendififneq ($(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.txtendififeq ($(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)endififeq ($(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=0x0apd/test.ini 0 2000 777selabel=u:object_r:apd_file:s0 capabilities=0x0apd/apd.txt 0 2000 777selabel=u:object_r:apd_file:s0 capabilities=0x0apd/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, doeshave an IMAGES/ top-level subdirectory), replace the images tothe 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

其实就是定义 disttoolsout/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 这个文件的作用了。