Android OTA系统升级---原理三

最近公司的一个老的项目,现在客户在专网方面遇到一点问题,进行版本升级时,由于客户是公安,比较强硬,要求升级时不能擦除数据,这个可以简单的通过改下打包脚本下参数就能解决。还是花了很长时间来跟踪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")




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值