分析下 Android SDK 中制作OTA升级包的流程,详细说明全量和增量升级包的过程

制作OTA全量和增量的过程而言差异其实就是最后执行命令参数不同,全量升级包是先做出一个完整包含所有需要文件的目录

然后根据每个平台的基本配置去提取出需要的东西打包成一个升级包,下面来看如何做出一个完整包含所需文件的目录流程

执行 make otapackage 是制作全量升级包的命令

// build/core/Makefile
$(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(DISTTOOLS)
         @echo "Package OTA: $@"                                                                                                              
          MKBOOTIMG=$(MKBOOTIMG) \
            ./build/tools/releasetools/ota_from_target_files -v \
            -p $(HOST_OUT) \
            -k $(KEY_CERT_PAIR) $(TIMESTAMP_CHECK) \
            $(if $(OEM_OTA_CONFIG), -o $(OEM_OTA_CONFIG)) \
            $(BUILT_TARGET_FILES_PACKAGE) $@


 .PHONY: otapackage
 otapackage: $(INTERNAL_OTA_PACKAGE_TARGET)

我们可以看到 Makefile 中伪目标 otapackage,依赖关系如上,这里需要知道平台配置的基本设置,一般是

/ device/xxx/BoardConfigCommon.mk , 这里截取一小段看下 
# 0: no mboot; 1: mboot in SPI ; 2: mboot in EMMC ; 3: mboot in EMMC ,SPI(pm)
 BOARD_MBOOTIMAGE := 1
 BOARD_TEEIMAGE = $(BUILD_WITH_TEE)
 #BOARD_RTPMIMAGE := true
 BOARD_DTBIMAGE := true

 # OTA config
 OTA_WITH_TIMESTAMP := 0
 OTA_WIPECACHE := 0

 OTA_WITH_MBOOT = $(BOARD_MBOOTIMAGE)
 OTA_RELOAD_ENV := 1
 # 0: no tv; 1: tv images ; 2: tv files
 OTA_WITH_TV := 1
 # 0: no tvconfig; 1: tvconfig.img ; 2: add/delete config files
 OTA_WITH_TVCONFIG := 0
 OTA_WITH_TEE = $(BOARD_TEEIMAGE)
 OTA_WITH_RTPM = $(BOARD_RTPMIMAGE)
 OTA_WITH_DTB = $(BOARD_DTBIMAGE)

截取片段可以看出我们可以通过配置中的定义是否在制作升级包的时候去包含进去。

下面我们来分析流程:

这里以平台名 aosp_ponkan32为例 做出 aosp_ponkan32-target_files-ANMI-02.70.020.04.01.BIONIC.C2 这样的完整目录,这里的名字大家可以根据自己平台可以看出 我这里是 TARGET_PRODUCT=aosp_ponkan32, 流程分析中注释以 // , /*** ***/ 为主,再次强调流程是以我的平台为主,具体要看平台配置,但是整体流程大体没有什么差异。编译OTA升级包时候,前提是必须要整体编译SDK ,并且在和SDK 同级目录下会有一个 image/xxx/的目录包含了一些image和脚本会有用到 大家可以看下流程注释中有写

$(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)
                 
           // zip_root := $(intermediates)/$(name)     
           //删除之前的 out\target\product\ponkan 下的目录和压缩包  (aosp_ponkan32-target_files-ANMI-02.70.020.04.01.BIONIC.C2)
           @echo "Package target files: $@"
           $(hide) rm -rf $@ $(zip_root)
           $(hide) mkdir -p $(dir $@) $(zip_root)
           @# Components of the recovery image
           // 创建 RECOVERY 目录
           $(hide) mkdir -p $(zip_root)/RECOVERY
           // 把 out\target\product\ponkan\recovery\root中的内容 拷贝到 target_files中 RCOVERY目录下
           $(hide) $(call package_files-copy-root, \
                   $(TARGET_RECOVERY_ROOT_OUT),$(zip_root)/RECOVERY/RAMDISK)/***                  
   ifneq ($(strip $(TARGET_NO_KERNEL)),true)
     INSTALLED_KERNEL_TARGET := $(PRODUCT_OUT)/kernel
   else
     INSTALLED_KERNEL_TARGET :=                                                                                                                 
   endif         
   
    // 定义了执行,把out\target\product\ponkan\kernel 拷贝到  RECOVERY/kernel            
 ***/            
   ifdef INSTALLED_KERNEL_TARGET
           $(hide) $(ACP) $(INSTALLED_KERNEL_TARGET) $(zip_root)/RECOVERY/kernel
   endif/***  
   TARGET_NO_BOOTLOADER := true 
  ifneq ($(strip $(TARGET_NO_BOOTLOADER)),true)
     INSTALLED_BOOTLOADER_MODULE := $(PRODUCT_OUT)/bootloader
     ifeq ($(strip $(TARGET_BOOTLOADER_IS_2ND)),true)
       INSTALLED_2NDBOOTLOADER_TARGET := $(PRODUCT_OUT)/2ndbootloader
     else
       INSTALLED_2NDBOOTLOADER_TARGET :=
     endif
   else  // 走这一步
     INSTALLED_BOOTLOADER_MODULE :=
     INSTALLED_2NDBOOTLOADER_TARGET :=
   endif # TARGET_NO_BOOTLOADER        
   
   所以     
   INSTALLED_BOOTLOADER_MODULE :=
     INSTALLED_2NDBOOTLOADER_TARGET :=
   
 ***/ 
 //不执行
   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
   
   // BOARD_KERNEL_BASE  := 0x20280000 定义了把 0x20280000 写入 RECOVERY/base
   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

 // 创建 BOOT 目录
   // 把 out\target\product\ponkan\root中的内容 拷贝到 target_files中 
   // BOOT 目录下
          @# Components of the boot image
           $(hide) mkdir -p $(zip_root)/BOOT
           $(hide) $(call package_files-copy-root, \
                   $(TARGET_ROOT_OUT),$(zip_root)/BOOT/RAMDISK)
                   
   // 定义了执行,把out\target\product\ponkan\kernel 拷贝到  BOOT/kernel                   
   ifdef INSTALLED_KERNEL_TARGET
           $(hide) $(ACP) $(INSTALLED_KERNEL_TARGET) $(zip_root)/BOOT/kernel
   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
   
   // BOARD_KERNEL_BASE  := 0x20280000 定义了把 0x20280000 写入 BOOT/base
   ifdef BOARD_KERNEL_BASE
           $(hide) echo "$(BOARD_KERNEL_BASE)" > $(zip_root)/BOOT/base
   endif  // 没定义不执行
   ifdef BOARD_KERNEL_PAGESIZE
           $(hide) echo "$(BOARD_KERNEL_PAGESIZE)" > $(zip_root)/BOOT/pagesize
   endif
   
   // ./build/core/definitions.mk INSTALLED_RADIOIMAGE_TARGET :=
   // 没有东西 不执行创建和拷贝
   $(hide) $(foreach t,$(INSTALLED_RADIOIMAGE_TARGET),\
               mkdir -p $(zip_root)/RADIO; \
               $(ACP) $(t) $(zip_root)/RADIO/$(notdir $(t));)
               
   // 定义了执行,把out\target\product\ponkan\system 拷贝到 SYSTEM下
   @# Contents of the system image
   $(hide) $(call package_files-copy-root, \
           $(SYSTEMIMAGE_SOURCE_DIR),$(zip_root)/SYSTEM)
   
   // 定义了执行,把out\target\product\ponkan\data 拷贝到 DATA下        
   @# Contents of the data image
   $(hide) $(call package_files-copy-root, \
           $(TARGET_OUT_DATA),$(zip_root)/DATA)
           
   // 没定义不执行       
 ifdef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
  @# Contents of the vendor image
  $(hide) $(call package_files-copy-root, \
          $(TARGET_OUT_VENDOR),$(zip_root)/VENDOR)
 endif// OTA_WITH_TV := 1   执行
// 在target_files 目录下建立了一个TV 目录
// OTA tv image path: ./../images/lollipop/ponkan/ 
// OTA tv image list: tvservice,tvcustomer,tvdatabase
 
   ifneq ($(filter 1 2,$(OTA_WITH_TV)),)
           $(hide) mkdir -p $(zip_root)/TV
           $(hide) if [ -n $(OTA_TV_IMAGE_PATH) ]; then echo "OTA tv image path: $(OTA_TV_IMAGE_PATH)"; else echo "OTA_TV_IMAGE_PATH not exist!"  ; exit 1; fi
           $(hide) if [ -n $(OTA_TV_IMAGE_LIST) ]; then echo "OTA tv image list: $(OTA_TV_IMAGE_LIST)"; else echo "OTA_TV_IMAGE_LIST not exist!"  ; exit 1; fi


 // OTA_TV_IMAGE_PATH := $(TOP)/../images/lollipop/ponkan/
 //  export OTA_TV_IMAGE_PATH=$(get_build_var OTA_TV_IMAGE_PATH)
 //  从 $(TOP)/../images/lollipop/ponkan/中把 tv3个img 拷贝到TV 目录下
   ifeq ($(OTA_WITH_TV),1)
           @# Contents of the tv images
           $(hide) $(foreach t,$(shell echo $(OTA_TV_IMAGE_LIST) | sed "s/,/ /g"), \
                       $(ACP) $(OTA_TV_IMAGE_PATH)/$(t).img $(zip_root)/TV/$(t).img;)
   else ifeq ($(OTA_WITH_TV),2)
           @# Contents of the tv files
           $(hide) $(foreach t,$(shell echo $(OTA_TV_IMAGE_LIST) | sed "s/,/ /g"), \
                       cp -rf $(OTA_TV_IMAGE_PATH)/$(t) $(zip_root)/TV/;)
           $(hide) find $(zip_root)/TV -name .svn | xargs rm -rf
   endif
   endif//  OTA_WITH_TVCONFIG = 0 不执行
 ifneq ($(filter 1 2,$(OTA_WITH_TVCONFIG)),)
          $(hide) mkdir -p $(zip_root)/TVCONFIG
          $(hide) if [ -n $(OTA_TVCONFIG_IMAGE_PATH) ]; then echo "OTA tvconfig image path: $(OTA_TVCONFIG_IMAGE_PATH)"; else echo "OTA_TVCONFI  G_IMAGE_PATH not exist!"; exit 1; fi
          $(hide) if [ -n $(OTA_TVCONFIG_IMAGE_LIST) ]; then echo "OTA tvconfig image list: $(OTA_TVCONFIG_IMAGE_LIST)"; else echo "OTA_TVCONFI  G_IMAGE_LIST not exist!"; exit 1; fi
  ifeq ($(OTA_WITH_TVCONFIG),1)
          @# Contents of the tvconfig images
          $(hide) $(ACP) $(OTA_TVCONFIG_IMAGE_PATH)/tvconfig.img $(zip_root)/TVCONFIG/tvconfig.img
  else ifeq ($(OTA_WITH_TVCONFIG),2)
          @# Contents of the tvconfig files
          $(hide) $(foreach t,$(shell echo $(OTA_TVCONFIG_IMAGE_LIST) | sed "s/,/ /g"), \
                      cp -rf $(OTA_TVCONFIG_IMAGE_PATH)/$(t) $(zip_root)/TVCONFIG/;)
          $(hide) find $(zip_root)/TVCONFIG -name .svn | xargs rm -rf
  
          $(hide) mkdir -p $(zip_root)/TVCONFIG_DEL
          $(hide) if [ -n $(OTA_TVCONFIG_DELETE_LIST) ]; then echo "OTA tvconfig delete list: $(OTA_TVCONFIG_DELETE_LIST)"; else echo "OTA_TVCO  NFIG_DELETE_LIST not exist!"; exit 1; fi
          $(hide) $(foreach t,$(shell echo $(OTA_TVCONFIG_DELETE_LIST) | sed "s/,/ /g"), \
                      cp -rf $(OTA_TVCONFIG_IMAGE_PATH)/$(t) $(zip_root)/TVCONFIG_DEL/;)
          $(hide) find $(zip_root)/TVCONFIG_DEL -name .svn | xargs rm -rf
  endif
  endif// OTA_WITH_MBOOT = 1 定义执行
 // OTA mboot image: ./../images/lollipop/ponkan/bfe_app.bin
 // OTA rom_boot image: ./../images/lollipop/ponkan/bfe_boot.bin

  ifneq ($(filter 1 2 3,$(OTA_WITH_MBOOT)),)  //执行
           @# Contents of the mboot
           $(hide) if [ -n $(OTA_MBOOT_IMAGE) ]; then echo "OTA mboot image: $(OTA_MBOOT_IMAGE)"; else echo "OTA_MBOOT_IMAGE not exist!"; exit 1  ; fi
           $(hide) mkdir -p $(zip_root)/MBOOT
           $(hide) $(ACP) $(OTA_MBOOT_IMAGE) $(zip_root)/MBOOT/$(notdir $(OTA_MBOOT_IMAGE))
   ifneq ($(OTA_WITH_MBOOT),1)  //执行
           $(hide) if [ -n $(OTA_MBOOT_EMMC_ROM_IMAGE) ]; then echo "OTA rom_boot image: $(OTA_MBOOT_EMMC_ROM_IMAGE)"; else echo "OTA_MBOOT_EMMC  _ROM_IMAGE not exist!"; exit 1; fi
           $(hide) $(ACP) $(OTA_MBOOT_EMMC_ROM_IMAGE) $(zip_root)/MBOOT/$(notdir $(OTA_MBOOT_EMMC_ROM_IMAGE))
   endif
   ifeq ($(OTA_WITH_MBOOT),3)
           @# Contents of the pm
           $(hide) if [ -n $(OTA_PM_IMAGE) ]; then echo "OTA PM image: $(OTA_PM_IMAGE)"; else echo "OTA_PM_IMAGE not exist!"; exit 1; fi
           $(hide) $(ACP) $(OTA_PM_IMAGE) $(zip_root)/MBOOT/PM51.bin
   endif
   endif// 没定义不执行
   ifeq ($(OTA_WITH_TEE),true)
           @# Contents of the tee
   ifeq ($(BUILD_WITH_SECURE_BOOT),true)
           $(hide) if [ -n $(OTA_TEE_AES_IMAGE) ]; then echo "OTA tee image: $(OTA_TEE_AES_IMAGE)"; else echo "OTA_TEE_AES_IMAGE not e  xist!"; exit 1; fi
           $(hide) mkdir -p $(zip_root)/TEE
           $(hide) $(ACP) $(OTA_TEE_AES_IMAGE) $(zip_root)/TEE/tee.aes
   ifneq ($(BUILD_WITH_SECURE_MERGE),true)
           $(hide) if [ -n $(OTA_TEE_SECUREINFO_IMAGE) ]; then echo "OTA tee SecureInfo image: $(OTA_TEE_SECUREINFO_IMAGE)"; else echo   "OTA_TEE_SECUREINFO_IMAGE not exist!"; exit 1; fi
           $(hide) $(ACP) $(OTA_TEE_SECUREINFO_IMAGE) $(zip_root)/TEE/secure_info_tee.bin
   endif
   else
           $(hide) if [ -n $(OTA_TEE_IMAGE) ]; then echo "OTA tee image: $(OTA_TEE_IMAGE)"; else echo "OTA_TEE_IMAGE not exist!"; exit   1; fi
           $(hide) mkdir -p $(zip_root)/TEE
           $(hide) $(ACP) $(OTA_TEE_IMAGE) $(zip_root)/TEE/tee.bin
   endif
   ifneq ($(BUILD_WITH_SECURE_MERGE),true)
           $(hide) $(ACP) $(OTA_NUTTX_IMAGE) $(zip_root)/TEE/nuttx_config.bin
   endif
   endif
  
   // 没定义不执行
    ifeq ($(OTA_WITH_OPTEE),true)
           @# Contents of the optee
   ifeq ($(BUILD_WITH_NS_UBOOT),true)
           $(hide) if [ -n $(OTA_OPTEE_AES_IMAGE) ]; then echo "OTA optee image: $(OTA_OPTEE_AES_IMAGE)"; else echo "OTA_OPTEE_AES_IMA  GE not exist!"; exit 1; fi
           $(hide) mkdir -p $(zip_root)/OPTEE
           $(hide) $(ACP) $(OTA_OPTEE_AES_IMAGE) $(zip_root)/OPTEE/tee.aes
   else
           $(hide) if [ -n $(OTA_OPTEE_IMAGE) ]; then echo "OTA optee image: $(OTA_OPTEE_IMAGE)"; else echo "OTA_OPTEE_IMAGE not exist  !"; exit 1; fi
           $(hide) mkdir -p $(zip_root)/OPTEE
           $(hide) $(ACP) $(OTA_OPTEE_IMAGE) $(zip_root)/OPTEE/tee.bin
   endif
   endif 


 // 没定义不执行
   ifeq ($(OTA_WITH_ARMFW),true)
           @# Contents of the armfw
   ifeq ($(BUILD_WITH_NS_UBOOT),true)
           $(hide) if [ -n $(OTA_ARMFW_AES_IMAGE) ]; then echo "OTA armfw image: $(OTA_ARMFW_AES_IMAGE)"; else echo "OTA_ARMFW_AES_IMA  GE not exist!"; exit 1; fi
           $(hide) mkdir -p $(zip_root)/OPTEE
           $(hide) $(ACP) $(OTA_ARMFW_AES_IMAGE) $(zip_root)/OPTEE/bl31.aes
   else
           $(hide) if [ -n $(OTA_ARMFW_IMAGE) ]; then echo "OTA armfw image: $(OTA_ARMFW_IMAGE)"; else echo "OTA_ARMFW_IMAGE not exist  !"; exit 1; fi
           $(hide) mkdir -p $(zip_root)/OPTEE
           $(hide) $(ACP) $(OTA_ARMFW_IMAGE) $(zip_root)/OPTEE/bl31.bin
   endif
   endif
   
 // 没定义不执行
   ifeq ($(OTA_WITH_RTPM),true)
           @# Contents of the rtpm
           $(hide) if [ -n $(OTA_RTPM_IMAGE) ]; then echo "OTA rtpm image: $(OTA_RTPM_IMAGE)"; else echo "OTA_RTPM_IMAGE not exist!";   exit 1; fi
           $(hide) mkdir -p $(zip_root)/RTPM
           $(hide) $(ACP) $(OTA_RTPM_IMAGE) $(zip_root)/RTPM/RT_PM.bin
   endif


 // 没定义不执行
   ifneq ($(filter 1 2,$(OTA_WITH_URSA)),)
           @# Contents of the ursa
           $(hide) if [ -n $(OTA_URSA_IMAGE) ]; then echo "OTA ursa image: $(OTA_URSA_IMAGE)"; else echo "OTA_URSA_IMAGE not exist!";   exit 1; fi
           $(hide) mkdir -p $(zip_root)/URSA
   ifeq ($(OTA_WITH_URSA),1)
           $(hide) $(ACP) $(OTA_URSA_IMAGE) $(zip_root)/URSA/ursa.bin
   endif
   ifeq ($(OTA_WITH_URSA),2)
           $(hide) $(ACP) $(OTA_URSA_IMAGE) $(zip_root)/URSA/ursa_ap.bin
   endif
   endif
   
 // 没定义不执行
   ifeq ($(OTA_WITH_RAPTORS),true)
           @# Contents of the raptors
           $(hide) if [ -n $(OTA_RAPTORS_IMAGE) ]; then echo "OTA raptors image: $(OTA_RAPTORS_IMAGE)"; else echo "OTA_RAPTORS_IMAGE n  ot exist!"; exit 1; fi
           $(hide) mkdir -p $(zip_root)/RAPTORS
           $(hide) $(ACP) $(OTA_RAPTORS_IMAGE) $(zip_root)/RAPTORS/raptors.bin
   endif// OTA_WITH_DTB = true 定义执行
 // OTA dtb image: ./../images/lollipop/ponkan/dtb.bin
 ifeq ($(OTA_WITH_DTB),true)
        @# Contents of the dtb
        $(hide) if [ -n $(OTA_DTB_IMAGE) ]; then echo "OTA dtb image: $(OTA_DTB_IMAGE)"; else echo "OTA_DTB_IMAGE not exist!"; exit 1; fi
        $(hide) mkdir -p $(zip_root)/DTB
        $(hide) $(ACP) $(OTA_DTB_IMAGE) $(zip_root)/DTB/dtb.bin
 endif
  /***
 创建 OTA/bin 目录
 PRIVATE_OTA_TOOLS := $(built_ota_tools) ,把built_ota_tools 列表下工具拷贝到OTA/bin目录下
 工具有 applypatch,applypatch_static,check_prereq,sqlite3,updater

 BUILT_TARGET_FILES_PACKAGE 依赖中有一个 INSTALLED_ANDROID_INFO_TXT_TARGET 这个
 INSTALLED_ANDROID_INFO_TXT_TARGET := $(PRODUCT_OUT)/android-info.txt
 把 这个文件拷贝到 OTA 目录下

 创建 META 目录,然后把一些信息写到对应的文件中去,这里就不详细说明了,还是有点复杂的这里需要大家慢慢分析
 文件有
 apkcerts.txt,
 misc_info.txt,
 filesystem_config.txt,
 recovery_filesystem_config.txt,
 boot_filesystem_config.txt,
 vendor_filesystem_config.txt


 ***/

           @# 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/
           @# 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
   ifdef 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
           $(hide) echo "default_system_dev_certificate=$(DEFAULT_SYSTEM_DEV_CERTIFICATE)" >> $(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
   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
  
           $(call generate-userimage-prop-dictionary, $(zip_root)/META/misc_info.txt)

           @# 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
           $(hide) (cd $(zip_root) && zip -q ../$(notdir $@) META/*filesystem_config.txt)
           $(hide) ./build/tools/releasetools/add_img_to_target_files -p $(HOST_OUT) $@
   
   ifneq ($(TARGET_PRODUCT),sdk)
   ifeq ($(filter generic%,$(TARGET_DEVICE)),)
   ifneq ($(TARGET_NO_KERNEL),true)
   ifneq ($(recovery_fstab),)
   
   # -----------------------------------------------------------------
           $(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
   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

           $(call generate-userimage-prop-dictionary, $(zip_root)/META/misc_info.txt)
           @# 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


          $(hide) zipinfo -1 $@ | awk 'BEGIN { FS="SYSTEM/" } /^SYSTEM\// {print "system/" $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -S $(SE  LINUX_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 $(SE  LINUX_FC) > $(zip_root)/META/vendor_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
          $(hide) (cd $(zip_root) && zip -q ../$(notdir $@) META/*filesystem_config.txt)
          $(hide) ./build/tools/releasetools/add_img_to_target_files -p $(HOST_OUT) $@ 
// 这里如果一些工具没有的话会生成,如果你编译的整个SDK ,这些一般都会做好了。
DISTTOOLS :=  $(HOST_OUT_EXECUTABLES)/minigzip \
             $(HOST_OUT_EXECUTABLES)/mkbootfs \
             $(HOST_OUT_EXECUTABLES)/mkimage \
             $(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 \
             $(HOST_OUT_EXECUTABLES)/boot_signer/***
 Package OTA: out/target/product/ponkan/aosp_ponkan32-ota-ANMI-02.70.020.04.01.BIONIC.C2.zip
 MKBOOTIMG=out/host/linux-x86/bin/mkbootimg \
    ./build/tools/releasetools/ota_from_target_files -v \
    -p out/host/linux-x86 \
    -k build/target/product/security/testkey -n \


 ***/
 $(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(DISTTOOLS)
         @echo "Package OTA: $@"                                                                                                              
          MKBOOTIMG=$(MKBOOTIMG) \
            ./build/tools/releasetools/ota_from_target_files -v \
            -p $(HOST_OUT) \
            -k $(KEY_CERT_PAIR) $(TIMESTAMP_CHECK) \
            $(if $(OEM_OTA_CONFIG), -o $(OEM_OTA_CONFIG)) \
            $(BUILT_TARGET_FILES_PACKAGE) $@

上面就是OTA全量升级包的流程之一先做出完整的需要的包,第二步流程等下我们分析 ota_from_target_files 这个 python脚本,这个才是重点。