make otapackage 流程

 我们知道,在Android源码整编后执行make otapackage命令即可生成OTA整包,但除此之外它还完成了哪些功能?具体又是如何完成的呢?事实上,在OTA升级过程中命令make otapackage完成了三件事情:

  • 重新对system.img文件进行了打包;
  • 生成差分资源包,路径为out/target/product/<product-name>/obj/PACKAGING/target_files_from_intermedias/<product-name>-target_files-<version-name>.zip,差分资源包用于生成整包和差分包;
  • 生成OTA整包,路径为out/target/product/<product-name>/<product-name>-ota-<version-name>.zip

        本文将对此命令的执行过程进行分析。

[plain] view plain copy print ?
  1. # -----------------------------------------------------------------  
  2. # OTA update package  
  3.   
  4. name := $(TARGET_PRODUCT)  
  5. ifeq ($(TARGET_BUILD_TYPE),debug)  
  6.   name := $(name)_debug  
  7. endif  
  8. name := $(name)-ota-$(FILE_NAME_TAG)  
  9.   
  10. INTERNAL_OTA_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip  
  11.   
  12. $(INTERNAL_OTA_PACKAGE_TARGET): KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR)  
  13.   
  14. $(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(OTATOOLS)  
  15.     @echo "Package OTA: $@"  
  16.     $(hide) ./build/tools/releasetools/ota_from_target_files -v \  
  17.        -n \  
  18.        -p $(HOST_OUT) \  
  19.            -k $(KEY_CERT_PAIR) \  
  20.            $(BUILT_TARGET_FILES_PACKAGE) $@  
  21.   
  22. .PHONY: otapackage  
  23. otapackage: $(INTERNAL_OTA_PACKAGE_TARGET)  
  24.   
  25. # -----------------------------------------------------------------  
  26. # The update package  
  27.   
  28. name := $(TARGET_PRODUCT)  
  29. ifeq ($(TARGET_BUILD_TYPE),debug)  
  30.   name := $(name)_debug  
  31. endif  
  32. name := $(name)-img-$(FILE_NAME_TAG)  
[plain] view plain copy print ?
  1. 代码段1 Makefile文件中目标otapackage的执行代码  

       

        首先,make otapackage命令会执行Makefile(./build/core/Makefile)中otapackage的目标代码(如代码1所示)。由代码可知,otapackage目标的执行只依赖于$(INTERNAL_OTA_PACKAGE_TARGET),而不存在任何规则(根据Makefile语法,规则必须以TAB键开始,而目标otapackage的定义之后却是变量name的声明,因此不存在规则),因此只需要关注目标$(INTERNAL_OTA_PACKAGE_TARGET)的生成。显然,此目标的生成依赖于目标文件:$(BUILT_TARGET_FILES_PACKAGE)$(OTATOOLS),且其执行的命令为./build/tools/releasetools/ota_from_target_files。也就是说,make otapackage所完成的功能全是通过这两个目标文件和执行的命令完成的,我们将分别对这三个关键点进行分析。

$(OTATOOLS)

        目标文件OTATOOLS的编译规则如下所示

[plain] view plain copy print ?
  1. OTATOOLS :=  $(HOST_OUT_EXECUTABLES)/minigzip \  
  2.       $(HOST_OUT_EXECUTABLES)/mkbootfs \  
  3.       $(HOST_OUT_EXECUTABLES)/mkbootimg \  
  4.       $(HOST_OUT_EXECUTABLES)/fs_config \  
  5.       $(HOST_OUT_EXECUTABLES)/mkyaffs2image \  
  6.       $(HOST_OUT_EXECUTABLES)/zipalign \  
  7.       $(HOST_OUT_EXECUTABLES)/aapt \  
  8.       $(HOST_OUT_EXECUTABLES)/bsdiff \  
  9.       $(HOST_OUT_EXECUTABLES)/imgdiff \  
  10.       $(HOST_OUT_JAVA_LIBRARIES)/dumpkey.jar \  
  11.       $(HOST_OUT_JAVA_LIBRARIES)/signapk.jar \  
  12.       $(HOST_OUT_EXECUTABLES)/mkuserimg.sh \  
  13.       $(HOST_OUT_EXECUTABLES)/genext2fs \  
  14.       $(HOST_OUT_EXECUTABLES)/tune2fs \  
  15.       $(HOST_OUT_EXECUTABLES)/e2fsck \  
  16.       $(HOST_OUT_EXECUTABLES)/make_ext4fs  
  17.   
  18. .PHONY: otatools  
  19. otatools: $(OTATOOLS)  

代码段2 $(OTATOOLS)的编译规则

        可以看出变量OTATOOLS为系统中一系列文件的集合。那么这些文件又有什么用处呢? 事实上,这些文件用于压缩(minigzip:用于gzip文件;make_ext4fs:将文件转换为ext4类型;mkyaffs2image:用于yaffs文件系统;......)、解压缩、差分(bsdiff,imgdiff)、签名(singapk.jar)等功能,结合代码段1可得到如下结论:目标$(INTERNAL_OTA_PACKAGE_TARGET)的执行依赖于这一系列系统工具--仅此而已。也就是说,目标文件$(OTATOOLS)仅仅指定了命令执行所需要的工具,并未执行任何操作。

        注:变量$(HOST_OUT_EXECUTABLES)指代的是out/host/linux-x86/bin目录,而变量$(HOST_OUT_JAVA_LIBRARIES)/表示的是out/host/linux-x86/framework目录,这意味着我们可以从此目录下找到上述工具,并为我们所用。

1.2$(BUILT_TARGET_FILES_PACKAGE)

        目标OTATOOLS指明了执行make otapackage命令所需要的系统工具,而目标$(BUILT_TARGE_FILES_PACKAGE)的生成则完成了两件事:重新打包system.img文件和生成差分资源包。$(BUILT_TARGE_FILES_PACKAGE)的编译规则如下所示:

[plain] view plain copy print ?
  1. # -----------------------------------------------------------------  
  2. # A zip of the directories that map to the target filesystem.  
  3. # This zip can be used to create an OTA package or filesystem image  
  4. # as a post-build step.  
  5. #  
  6. name := $(TARGET_PRODUCT)  
  7. ifeq ($(TARGET_BUILD_TYPE),debug)  
  8.   name := $(name)_debug  
  9. endif  
  10. name := $(name)-target_files-$(FILE_NAME_TAG)  
  11.   
  12. intermediates := $(call intermediates-dir-for,PACKAGING,target_files)  
  13. BUILT_TARGET_FILES_PACKAGE := $(intermediates)/$(name).zip  
  14. $(BUILT_TARGET_FILES_PACKAGE): intermediates := $(intermediates)  
  15. $(BUILT_TARGET_FILES_PACKAGE): \  
  16.         zip_root := $(intermediates)/$(name)  
  17.   
  18. # $(1): Directory to copy  
  19. # $(2): Location to copy it to  
  20. # The "ls -A" is to prevent "acp s/* d" from failing if s is empty.  
  21. define package_files-copy-root  
  22.   if [ -d "$(strip $(1))" -a "$$(ls -A $(1))" ]; then \  
  23.     mkdir -p $(2) && \  
  24.     $(ACP) -rd $(strip $(1))/* $(2); \  
  25.   fi  
  26. endef  
  27.   
  28. built_ota_tools := \  
  29.     $(call intermediates-dir-for,EXECUTABLES,applypatch)/applypatch \  
  30.     $(call intermediates-dir-for,EXECUTABLES,applypatch_static)/applypatch_static \  
  31.     $(call intermediates-dir-for,EXECUTABLES,check_prereq)/check_prereq \  
  32.     $(call intermediates-dir-for,EXECUTABLES,sqlite3)/sqlite3 \  
  33.     $(call intermediates-dir-for,EXECUTABLES,updater)/updater  
  34. $(BUILT_TARGET_FILES_PACKAGE): PRIVATE_OTA_TOOLS := $(built_ota_tools)  
  35.   
  36. $(BUILT_TARGET_FILES_PACKAGE): PRIVATE_RECOVERY_API_VERSION := $(RECOVERY_API_VERSION)  
  37.   
  38. ifeq ($(TARGET_RELEASETOOLS_EXTENSIONS),)  
  39. # default to common dir for device vendor  
  40. $(BUILT_TARGET_FILES_PACKAGE): tool_extensions := $(TARGET_DEVICE_DIR)/../common  
  41. else  
  42. $(BUILT_TARGET_FILES_PACKAGE): tool_extensions := $(TARGET_RELEASETOOLS_EXTENSIONS)  
  43. endif  
  44.   
  45. # Depending on the various images guarantees that the underlying  
  46. # directories are up-to-date.  
  47.   
  48. ifeq ($(TARGET_USERIMAGES_USE_EXT4),true)  
  49. $(BUILT_TARGET_FILES_PACKAGE): $(INSTALLED_CACHEIMAGE_TARGET)  
  50. endif  
  51.   
  52. $(BUILT_TARGET_FILES_PACKAGE): \  
  53.         $(INSTALLED_BOOTIMAGE_TARGET) \  
  54.         $(INSTALLED_RADIOIMAGE_TARGET) \  
  55.         $(INSTALLED_RECOVERYIMAGE_TARGET) \  
  56.         $(INSTALLED_FACTORYIMAGE_TARGET) \  
  57.         $(INSTALLED_SYSTEMIMAGE) \  
  58.         $(INSTALLED_CACHEIMAGE_TARGET) \  
  59.         $(INSTALLED_USERDATAIMAGE_TARGET) \  
  60.         $(INSTALLED_SECROIMAGE_TARGET) \  
  61.         $(INSTALLED_ANDROID_INFO_TXT_TARGET) \  
  62.         $(built_ota_tools) \  
  63.         $(APKCERTS_FILE) \  
  64.         $(HOST_OUT_EXECUTABLES)/fs_config \  
  65.         | $(ACP)  
  66.     @echo "Package target files: $@"  
  67.     $(hide) rm -rf $@ $(zip_root)  
  68.     $(hide) mkdir -p $(dir $@) $(zip_root)  
  69.     @# Components of the recovery image  
  70.     $(hide) mkdir -p $(zip_root)/RECOVERY  
  71.     $(hide) $(call package_files-copy-root, \  
  72.         $(TARGET_RECOVERY_ROOT_OUT),$(zip_root)/RECOVERY/RAMDISK)  
  73. ifdef INSTALLED_KERNEL_TARGET  
  74.     $(hide) $(ACP) $(INSTALLED_KERNEL_TARGET) $(zip_root)/RECOVERY/kernel  
  75.     $(hide) $(ACP) $(recovery_ramdisk) $(zip_root)/RECOVERY/ramdisk  
  76. endif  
  77. ifdef INSTALLED_2NDBOOTLOADER_TARGET  
  78.     $(hide) $(ACP) \  
  79.         $(INSTALLED_2NDBOOTLOADER_TARGET) $(zip_root)/RECOVERY/second  
  80. endif  
  81. ifdef BOARD_KERNEL_CMDLINE  
  82.     $(hide) echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/RECOVERY/cmdline  
  83. endif  
  84. ifdef BOARD_KERNEL_BASE  
  85.     $(hide) echo "$(BOARD_KERNEL_BASE)" > $(zip_root)/RECOVERY/base  
  86. endif  
  87.     @# Components of the factory image  
  88.     $(hide) mkdir -p $(zip_root)/FACTORY  
  89.     $(hide) $(call package_files-copy-root, \  
  90.         $(TARGET_FACTORY_ROOT_OUT),$(zip_root)/FACTORY/RAMDISK)  
  91. ifdef INSTALLED_KERNEL_TARGET  
  92.     $(hide) $(ACP) $(INSTALLED_KERNEL_TARGET) $(zip_root)/FACTORY/kernel  
  93. endif  
  94. ifdef BOARD_KERNEL_PAGESIZE  
  95.     $(hide) echo "$(BOARD_KERNEL_PAGESIZE)" > $(zip_root)/RECOVERY/pagesize  
  96. endif  
  97. ifdef INSTALLED_2NDBOOTLOADER_TARGET  
  98.     $(hide) $(ACP) \  
  99.         $(INSTALLED_2NDBOOTLOADER_TARGET) $(zip_root)/FACTORY/second  
  100. endif  
  101. ifdef BOARD_KERNEL_CMDLINE  
  102.     $(hide) echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/FACTORY/cmdline  
  103. endif  
  104. ifdef BOARD_KERNEL_BASE  
  105.     $(hide) echo "$(BOARD_KERNEL_BASE)" > $(zip_root)/FACTORY/base  
  106. endif  
  107.     @# Components of the boot image  
  108.     $(hide) mkdir -p $(zip_root)/BOOT  
  109.     $(hide) $(call package_files-copy-root, \  
  110.         $(TARGET_ROOT_OUT),$(zip_root)/BOOT/RAMDISK)  
  111. ifdef INSTALLED_KERNEL_TARGET  
  112.     $(hide) $(ACP) $(INSTALLED_KERNEL_TARGET) $(zip_root)/BOOT/kernel  
  113.     $(hide) $(ACP) $(INSTALLED_RAMDISK_TARGET) $(zip_root)/BOOT/ramdisk  
  114. endif  
  115. ifdef INSTALLED_2NDBOOTLOADER_TARGET  
  116.     $(hide) $(ACP) \  
  117.         $(INSTALLED_2NDBOOTLOADER_TARGET) $(zip_root)/BOOT/second  
  118. endif  
  119. ifdef BOARD_KERNEL_CMDLINE  
  120.     $(hide) echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/BOOT/cmdline  
  121. endif  
  122. ifdef BOARD_KERNEL_BASE  
  123.     $(hide) echo "$(BOARD_KERNEL_BASE)" > $(zip_root)/BOOT/base  
  124. endif  
  125. ifdef BOARD_KERNEL_PAGESIZE  
  126.     $(hide) echo "$(BOARD_KERNEL_PAGESIZE)" > $(zip_root)/BOOT/pagesize  
  127. endif  
  128. #wschen  
  129. ifneq "" "$(CUSTOM_BUILD_VERNO)"  
  130.     $(hide) echo "$(CUSTOM_BUILD_VERNO)" > $(zip_root)/BOOT/board  
  131. endif  
  132.   
  133. #[eton begin]: added by LiuDekuan for u-boot update  
  134.     $(hide) $(ACP) $(PRODUCT_OUT)/uboot_eyang77_ics2.bin $(zip_root)/uboot.bin  
  135. #[eton end]  
  136.   
  137.     $(hide) $(foreach t,$(INSTALLED_RADIOIMAGE_TARGET),\  
  138.                 mkdir -p $(zip_root)/RADIO; \  
  139.                 $(ACP) $(t) $(zip_root)/RADIO/$(notdir $(t));)  
  140.     @# Contents of the system image  
  141.     $(hide) $(call package_files-copy-root, \  
  142.         $(SYSTEMIMAGE_SOURCE_DIR),$(zip_root)/SYSTEM)  
  143.     @# Contents of the data image  
  144.     $(hide) $(call package_files-copy-root, \  
  145.         $(TARGET_OUT_DATA),$(zip_root)/DATA)  
  146.     @# Extra contents of the OTA package  
  147.     $(hide) mkdir -p $(zip_root)/OTA/bin  
  148.     $(hide) $(ACP) $(INSTALLED_ANDROID_INFO_TXT_TARGET) $(zip_root)/OTA/  
  149.     $(hide) $(ACP) $(PRIVATE_OTA_TOOLS) $(zip_root)/OTA/bin/  
  150.     @# Security information of the OTA package  
  151.     @echo "[SEC OTA] Adding Security information to OTA package"  
  152.     @echo "[SEC OTA] path : mediatek/custom/$(MTK_PROJECT)/security/recovery/SEC_VER.txt"  
  153.     $(hide) $(ACP) mediatek/custom/$(MTK_PROJECT)/security/recovery/SEC_VER.txt $(zip_root)/OTA/  
  154.     @# Files that do not end up in any images, but are necessary to  
  155.     @# build them.  
  156.     $(hide) mkdir -p $(zip_root)/META  
  157.     $(hide) $(ACP) $(APKCERTS_FILE) $(zip_root)/META/apkcerts.txt  
  158.     $(hide) echo "$(PRODUCT_OTA_PUBLIC_KEYS)" > $(zip_root)/META/otakeys.txt  
  159.     $(hide) echo "recovery_api_version=$(PRIVATE_RECOVERY_API_VERSION)" > $(zip_root)/META/misc_info.txt  
  160. ifdef BOARD_FLASH_BLOCK_SIZE  
  161.     $(hide) echo "blocksize=$(BOARD_FLASH_BLOCK_SIZE)" >> $(zip_root)/META/misc_info.txt  
  162. endif  
  163. ifdef BOARD_BOOTIMAGE_PARTITION_SIZE  
  164.     $(hide) echo "boot_size=$(BOARD_BOOTIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt  
  165. endif  
  166. ifdef BOARD_RECOVERYIMAGE_PARTITION_SIZE  
  167.     $(hide) echo "recovery_size=$(BOARD_RECOVERYIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt  
  168. endif  
  169. ifdef BOARD_SYSTEMIMAGE_PARTITION_SIZE  
  170.     $(hide) echo "system_size=$(BOARD_SYSTEMIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt  
  171. endif  
  172. ifdef BOARD_SECROIMAGE_PARTITION_SIZE  
  173.     $(hide) echo "secro_size=$(BOARD_SECROIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt  
  174. endif  
  175. ifdef BOARD_CACHEIMAGE_PARTITION_SIZE  
  176.     $(hide) echo "cache_size=$(BOARD_CACHEIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt  
  177. endif  
  178. ifdef BOARD_USERDATAIMAGE_PARTITION_SIZE  
  179.     $(hide) echo "userdata_size=$(BOARD_USERDATAIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt  
  180. endif  
  181.     $(hide) echo "tool_extensions=$(tool_extensions)" >> $(zip_root)/META/misc_info.txt  
  182. ifdef mkyaffs2_extra_flags  
  183.     $(hide) echo "mkyaffs2_extra_flags=$(mkyaffs2_extra_flags)" >> $(zip_root)/META/misc_info.txt  
  184. endif  
  185. ifdef INTERNAL_USERIMAGES_SPARSE_EXT_FLAG  
  186.     $(hide) echo "extfs_sparse_flag=$(INTERNAL_USERIMAGES_SPARSE_EXT_FLAG)" >> $(zip_root)/META/misc_info.txt  
  187. endif  
  188.     $(hide) echo "default_system_dev_certificate=$(DEFAULT_KEY_CERT_PAIR)" >> $(zip_root)/META/misc_info.txt  
  189. ifdef PRODUCT_EXTRA_RECOVERY_KEYS  
  190.     $(hide) echo "extra_recovery_keys=$(PRODUCT_EXTRA_RECOVERY_KEYS)" >> $(zip_root)/META/misc_info.txt  
  191. endif  
  192.     @# Zip everything up, preserving symlinks  
  193.     $(hide) (cd $(zip_root) && zip -qry ../$(notdir $@) .)  
  194.     @# Run fs_config on all the system, boot ramdisk, and recovery ramdisk files in the zip, and save the output  
  195.     $(hide) zipinfo -1 $@ | awk 'BEGIN { FS="SYSTEM/" } /^SYSTEM\// {print "system/" $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config > $(zip_root)/META/filesystem_config.txt  
  196.     $(hide) zipinfo -1 $@ | awk 'BEGIN { FS="BOOT/RAMDISK/" } /^BOOT\/RAMDISK\// {print $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config > $(zip_root)/META/boot_filesystem_config.txt  
  197.     $(hide) zipinfo -1 $@ | awk 'BEGIN { FS="RECOVERY/RAMDISK/" } /^RECOVERY\/RAMDISK\// {print $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config > $(zip_root)/META/recovery_filesystem_config.txt  
  198.     $(hide) (cd $(zip_root) && zip -q ../$(notdir $@) META/*filesystem_config.txt)  
  199.   
  200.   
  201. target-files-package: $(BUILT_TARGET_FILES_PACKAGE)  
  202.   
  203.   
  204. ifneq ($(TARGET_PRODUCT),sdk)  
  205. ifeq ($(filter generic%,$(TARGET_DEVICE)),)  
  206. ifneq ($(TARGET_NO_KERNEL),true)  
  207. ifneq ($(recovery_fstab),)  

代码段3 $(BUILT_TARGE_FILES_PACKAGE)目标的编译规则

         system.img文件的重新打包是通过$(BUILT_TARGE_FILES_PACKAGE)的依赖条件$(INSTALLED_SYSTEMIMAGE)目标文件的编译来完成的,而$(BUILT_TARGE_FILES_PACKAGE)所有的执行命令(代码第66行至最后)都只为完成一件事,生成差分资源包所对应的目录并将其打包为ZIP包。具体的操作包括:

  • 创建$(zip_root)目录(代码第66~68行),$(zip_root)即out/target/product/<product-name>/obj/PACKAGING/target_files_from_intermedias/<product-name>-target_files-<version-name>;
  • 创建/$(zip_root)/RECOVERY目录并将COPY相关文件(代码69~86);
  • 创建/$(zip_root)/FACTORY目录并将COPY相关文件(代码87~106);
  • 创建/$(zip_root)/BOOT目录并将COPY相关文件(代码107~131);
  • 创建其他目录并COPY文件(代码132~191);
  • 将$(zip_root)目录压缩为资源差分包(代码192~198)等。

        经过目标文件$(BUILT_TARGE_FILES_PACKAGE)的执行后,system.img已经被重新打包,且差分资源包也已经生成,剩下的工作就是将差分资源包传递给ota_target_from_files代码,由它来生成OTA整包。

1.3 ota_target_from_files

         ota_target_from_files为python代码所写的一个可执行文件,其路径为./build/tools/releasetools/ota_target_from_files。在此目录中其他python代码文件的辅助下,ota_target_from_files主要完成两个功能:生成OTA整包和OTA差分包,分别是通过函数WriteFullOTAPackage和WriteIncrementalOTAPackage来实现的。显然make otapackage命令调用的就是函数WriteFullOTAPackage来生成OTA整包。

[python] view plain copy print ?
  1. def main(argv):  
  2.   
  3.   def option_handler(o, a):  
  4.     if o in ("-b""--board_config"):  
  5.       pass   # deprecated  
  6.     elif o in ("-k""--package_key"):  
  7.       OPTIONS.package_key = a  
  8.     elif o in ("-i""--incremental_from"):  
  9.       print "LiuDekuan: incremental_source = ", a  
  10.       OPTIONS.incremental_source = a  
  11.     elif o in ("-w""--wipe_user_data"):  
  12.       OPTIONS.wipe_user_data = True  
  13.     elif o in ("-n""--no_prereq"):  
  14.       OPTIONS.omit_prereq = True  
  15.     elif o in ("-e""--extra_script"):  
  16.       OPTIONS.extra_script = a  
  17.     elif o in ("-a""--aslr_mode"):  
  18.       if a in ("on""On""true""True""yes""Yes"):  
  19.         OPTIONS.aslr_mode = True  
  20.       else:  
  21.         OPTIONS.aslr_mode = False  
  22.     elif o in ("--worker_threads"):  
  23.       OPTIONS.worker_threads = int(a)  
  24.     elif o in ("-r""--preloader"):  
  25.       OPTIONS.preloader = a  
  26.     elif o in ("-l""--logo"):  
  27.       OPTIONS.logo = a  
  28.     elif o in ("-u""--uboot"):  
  29.       OPTIONS.uboot = a  
  30.     elif o in ("-d""--dsp"):  
  31.       OPTIONS.dsp = a  
  32.     else:  
  33.       return False  
  34.     return True  
  35.   
  36.   args = common.ParseOptions(argv, __doc__,  
  37.                              extra_opts="b:k:i:d:wne:r:l:u:d:a:",  
  38.                              extra_long_opts=["board_config=",  
  39.                                               "package_key=",  
  40.                                               "incremental_from=",  
  41.                                               "wipe_user_data",  
  42.                                               "no_prereq",  
  43.                                               "extra_script=",  
  44.                                               "preloader=",  
  45.                                               "logo=",  
  46.                                               "uboot=",  
  47.                                               "dsp=",  
  48.                                               "worker_threads=",  
  49.                                               "aslr_mode=",  
  50.                                               ],  
  51.                              extra_option_handler=option_handler)  
  52.   
  53.   if len(args) != 2:  
  54.     common.Usage(__doc__)  
  55.     sys.exit(1)  
  56.   if OPTIONS.extra_script is not None:  
  57.     OPTIONS.extra_script = open(OPTIONS.extra_script).read()  
  58.   
  59.   print "unzipping target target-files..."  
  60.   OPTIONS.input_tmp, input_zip = common.UnzipTemp(args[0])  
  61.   
  62.   OPTIONS.target_tmp = OPTIONS.input_tmp  
  63.   OPTIONS.info_dict = common.LoadInfoDict(input_zip)  
  64.   if OPTIONS.verbose:  
  65.     print "--- target info ---"  
  66.     common.DumpInfoDict(OPTIONS.info_dict)  
  67.   
  68.   if OPTIONS.device_specific is None:  
  69.     OPTIONS.device_specific = OPTIONS.info_dict.get("tool_extensions"None)  
  70.   if OPTIONS.device_specific is not None:  
  71.     OPTIONS.device_specific = os.path.normpath(OPTIONS.device_specific)  
  72.     print "using device-specific extensions in", OPTIONS.device_specific  
  73.   
  74.   temp_zip_file = tempfile.NamedTemporaryFile()  
  75.   output_zip = zipfile.ZipFile(temp_zip_file, "w",  
  76.                                compression=zipfile.ZIP_DEFLATED)  
  77.   
  78.   if OPTIONS.incremental_source is None:  
  79.     WriteFullOTAPackage(input_zip, output_zip)  
  80.     if OPTIONS.package_key is None:  
  81.       OPTIONS.package_key = OPTIONS.info_dict.get(  
  82.           "default_system_dev_certificate",  
  83.           "build/target/product/security/testkey")  
  84.   else:  
  85.     print "unzipping source target-files..."  
  86.     OPTIONS.source_tmp, source_zip = common.UnzipTemp(OPTIONS.incremental_source)  
  87.     OPTIONS.target_info_dict = OPTIONS.info_dict  
  88.     OPTIONS.source_info_dict = common.LoadInfoDict(source_zip)  
  89.     if OPTIONS.package_key is None:  
  90.       OPTIONS.package_key = OPTIONS.source_info_dict.get(  
  91.           "default_system_dev_certificate",  
  92.           "build/target/product/security/testkey")  
  93.     if OPTIONS.verbose:  
  94.       print "--- source info ---"  
  95.       common.DumpInfoDict(OPTIONS.source_info_dict)  
  96.     WriteIncrementalOTAPackage(input_zip, source_zip, output_zip)  
  97.   
  98.   output_zip.close()  
  99.   
  100.   SignOutput(temp_zip_file.name, args[1])  
  101.   temp_zip_file.close()  
  102.   
  103.   common.Cleanup()  
  104.   
  105.   print "done."  

代码段4 ota_from_target_files中的main函数

        目标$(INTERNAL_OTA_PACKAGE_TARGET)的执行中调用到ota_from_target_files(如代码段1所示),程序便会跳转到ota_from_target_files的main函数中(代码段4),main函数首先解析Makefile(或终端)传递过来的参数(代码3~51),之后将代码段3中生成的差分资源包赋给变量input_zip(代码第60行)并创建需要输出的ZIP包(整包或差分包);之后判断当前命令是生成整包还是差分包(代码78)。如是整包升级则调用函数WriteFullOTAPackage函数(代码79),其中参数input_zip是差分资源包,而output_zip即OTA整包;如是差分包升级则执行else分支(85~96),调用函数WriteIncrementalOTAPackage。

[python] view plain copy print ?
  1. def WriteFullOTAPackage(input_zip, output_zip):  
  2.   # TODO: how to determine this?  We don't know what version it will  
  3.   # be installed on top of.  For now, we expect the API just won't  
  4.   # change very often.  
  5.   script = edify_generator.EdifyGenerator(3, OPTIONS.info_dict)  
  6.   
  7.   metadata = {"post-build": GetBuildProp("ro.build.fingerprint", input_zip),  
  8.               "pre-device": GetBuildProp("ro.product.device", input_zip),  
  9.               "post-timestamp": GetBuildProp("ro.build.date.utc", input_zip),  
  10.               }  
  11.   
  12.   device_specific = common.DeviceSpecificParams(  
  13.       input_zip=input_zip,  
  14.       input_version=OPTIONS.info_dict["recovery_api_version"],  
  15.       output_zip=output_zip,  
  16.       script=script,  
  17.       input_tmp=OPTIONS.input_tmp,  
  18.       metadata=metadata,  
  19.       info_dict=OPTIONS.info_dict)  
  20.   
  21.   if not OPTIONS.omit_prereq:  
  22.     ts = GetBuildProp("ro.build.date.utc", input_zip)  
  23.     script.AssertOlderBuild(ts)  
  24.   
  25.   AppendAssertions(script, input_zip)  
  26.   device_specific.FullOTA_Assertions()  
  27.   
  28.   script.ShowProgress(0.50)  
  29.   
  30.   if OPTIONS.wipe_user_data:  
  31.     script.FormatPartition("/data")  
  32.   
  33.   if OPTIONS.selinux_fc is not None:  
  34.     WritePolicyConfig(OPTIONS.selinux_fc, output_zip)  
  35.   
  36.   script.FormatPartition("/system")  
  37.   script.Mount("/system")  
  38.   script.UnpackPackageDir("recovery""/system")  
  39.   script.UnpackPackageDir("system""/system")  
  40.   
  41.   (symlinks, retouch_files) = CopySystemFiles(input_zip, output_zip)  
  42.   script.MakeSymlinks(symlinks)  
  43.   if OPTIONS.aslr_mode:  
  44.     script.RetouchBinaries(retouch_files)  
  45.   else:  
  46.     script.UndoRetouchBinaries(retouch_files)  
  47.   
  48.   boot_img = common.GetBootableImage("boot.img""boot.img",  
  49.                                      OPTIONS.input_tmp, "BOOT")  
  50.   recovery_img = common.GetBootableImage("recovery.img""recovery.img",  
  51.                                          OPTIONS.input_tmp, "RECOVERY")  
  52.   MakeRecoveryPatch(output_zip, recovery_img, boot_img)  
  53.   
  54.   Item.GetMetadata(input_zip)  
  55.   Item.Get("system").SetPermissions(script)  
  56.   
  57.   common.CheckSize(boot_img.data, "boot.img", OPTIONS.info_dict)  
  58.   common.ZipWriteStr(output_zip, "boot.img", boot_img.data)  
  59.   script.ShowProgress(0.20)  
  60.   
  61.   script.ShowProgress(0.210)  
  62.   script.WriteRawImage("/boot""boot.img")  
  63.   
  64.   script.ShowProgress(0.10)  
  65.   device_specific.FullOTA_InstallEnd()  
  66.   
  67.   if OPTIONS.extra_script is not None:  
  68.     script.AppendExtra(OPTIONS.extra_script)  
  69.   
  70.   script.UnmountAll()  
  71.   script.AddToZip(input_zip, output_zip)  
  72.   WriteMetadata(metadata, output_zip)  

代码段5 ota_from_target_files文件中的WriteFullOTAPackage函数

        代码段5为WriteFullOTAPackage函数的定义,它所完成的功能便是将整包所需要的文件从差分资源包中读出并写入到整包中。同时,它还会向整包中的META-INFO/com/google/android/updater-script文件中写入一些操作命令(极其重要),在recovery模式下系统会根据这些命令并执行相应的操作以完成系统的升级功能。

你可能感兴趣的:(make otapackage 流程)