OTA制作及升级过程笔记

本文档详细介绍了Android系统的OTA(Over-the-Air)升级过程,包括升级包的制作、升级包的结构、Recovery模式的分析以及升级过程的详细步骤。重点讲解了update.zip包的生成,包括整包和差分包的制作,涉及到的工具如minigzip、make_ext4fs等。还探讨了update-script脚本的作用和执行流程,以及在升级过程中可能出现的问题和解决方案。
摘要由CSDN通过智能技术生成

1、概述

1.1   文档概要

前段时间学习了AndroidRecovery模式及OTA升级过程,为加深理解和防止以后遗忘,所以写这篇文档进行一个总结和梳理,以便日后查阅回顾。文档主要包括两部分,第一部分为OTA升级包的制作过程分析,第二部分为Recovery模式下OTA升级包安装过程的分析,其中包括Recovery模式分析及服务流程。

1.2   参考文献

《Recovery 开发指导》

Android系统Recovery工作原理之使用update.zip升级过程分析

OTA本质与实现流程分析

《Android系统启动过程分析》

2、OTA升级包制作工程

2.1  OTA升级简介

所谓OTA(Over-the-AirTechnology)是指手机终端通过无线网络下载远程服务器上的升级包,对系统或应用进行升级的技术。有关网络部分不做过多讨论,本文重点放在系统升级这一概念上。

图1 某android手机存储设备结构图

以PC机进行类比,假设计算机操作系统装在C盘,当加电启动时,引导程序会将C盘的系统程序装入内存并运行,而系统升级或重装系统,则是将C盘中原来的系统文件部分或全部重写。对于手机及其上的ANDROID系统而言,同样如此,需要一个存储系统文件的“硬盘”。

图1 是某款手机的存储设备结构图,其存储区(红色框图部分)分为四部分:SRAM、Nand Flash、SDRAM及外设地址空间。其中Nand Flash中存储着全部系统数据(通过专门的烧写工具将编译后的映象文件download到Nand Flash中,工具由IC厂商提供),包括boot.img、system.img、recovery.img等,因此Nand Flash即是上文所说的手机上的硬盘。图1最右部分(图中绿色框图部分)是Nand Flash存储区更详细的划分,我们将主要关注system分区(蓝色框图),因为OTA升级主要是对这部分系统数据的重写(当然boot分区也可升级)。除此之外,蓝黑色区域标示的misc分区也应值得注意,它在OTA升级中发挥着重要的作用。

OK,一言以蔽之,所谓OTA就是将升级包(zip压缩包)写入到系统存储区,因此我们需要考虑两个问题:1、升级包是如何生成的?2、升级包是如何写入到system分区的?

2.2  OTA升级包update.zip结构

2.2.1、 update.zip包的目录结构

         |----boot.img

         |----system/

         |----recovery/

               `|----recovery-from-boot.p

               `|----etc/
                       `|----install-recovery.sh

         |---META-INF/

             `|CERT.RSA

             `|CERT.SF

             `|MANIFEST.MF

             `|----com/

                    `|----google/

                           `|----android/

                                 `|----update-binary

                                 `|----updater-script

                           `|----android/

                                  `|----metadata

2.2.2、 update.zip包目录结构详解

以上是我们用命令makeotapackage 制作的update.zip包的标准目录结构。(和实际的略有不同)

1、boot.img是更新boot分区所需要的文件。这个boot.img主要包括kernel+ramdisk,包括应用会用到的一些库等等。可以将Android源码编译out/target/product/ xxxx /system/中的所有文件拷贝到这个目录来代替。

2、system/目录的内容在升级后会放在系统的system分区。主要用来更新系统的一些应用或则应用会用到的一些库等等。可以将Android源码编译out/target/product/xxxx/system/中的所有文件拷贝到这个目录来代替。

3、recovery/目录中的recovery-from-boot.p是boot.img和recovery.img的补丁(patch),主要用来更新recovery分区,其中etc/目录下的install-recovery.sh是执行更新的脚本。

4、update-binary是一个二进制文件,相当于一个脚本解释器能够识别updater-script中描述的操作。它是Android源码编译后生成的out/target/product/xxxx/system bin/updater文件,可将updater重命名为update-binary得到。该文件在具体的更新包中的名字由源码中bootable/recovery/install.c中的宏ASSUMED_UPDATE_BINARY_NAME的值而定。

5、updater-script:此文件是一个脚本文件,具体描述了更新过程。我们可以根据具体情况编写该脚本来适应我们的具体需求。该文件的命名由源码中bootable/recovery/updater/updater.c文件中的宏SCRIPT_NAME的值而定。

6、 metadata文件是描述设备信息及环境变量的元数据。主要包括一些编译选项,签名公钥,时间戳以及设备型号等。

7、我们还可以在包中添加userdata目录,来更新系统中的用户数据部分。这部分内容在更新后会存放在系统的/data目录下。

8、update.zip包的签名:update.zip更新包在制作完成后需要对其签名,否则在升级时会出现认证失败的错误提示。而且签名要使用和目标板一致的加密公钥。加密公钥及加密需要的三个文件在Android源码编译后生成的具体路径为:

              out/host/linux-x86/framework/signapk.jar 

              build/target/product/security/testkey.x509.pem        

               build/target/product/security/testkey.pk8。

我们用命令makeotapackage制作生成的update.zip包是已签过名的,如果自己做update.zip包时必须手动对其签名。具体的加密方法:

$ java –jar gingerbread/out/host/linux/framework/signapk.jar –wgingerbread/build/target/product/security/testkey.x509.pem      gingerbread/build/target/product/security/testkey.pk8update.zip update_signed.zip

以上命令在update.zip包所在的路径下执行,其中signapk.jartestkey.x509.pem以及testkey.pk8文件的引用使用绝对路径。update.zip 是我们已经打好的包,update_signed.zip包是命令执行完生成的已经签过名的包。

9、MANIFEST.MF:这个manifest文件定义了与包的组成结构相关的数据。类似Android应用的mainfest.xml文件。

10、CERT.RSA:与签名文件相关联的签名程序块文件,它存储了用于签名JAR文件的公共签名。

11、CERT.SF:这是JAR文件的签名文件,其中前缀CERT代表签名者。

另外,在具体升级时,对update.zip包检查时大致会分三步:①检验SF文件与RSA文件是否匹配。②检验MANIFEST.MF与签名文件中的digest是否一致。③检验包中的文件与MANIFEST中所描述的是否一致。

12、在做的MTK平台的项目(如8670、9976),需要增加与项目强相关的适配文件(scatter.txt、SEC_VER.txt、type.txt),scatter.txt分散加载文件,将可执行映像文件分散加载到不同的内存段(文件内容:指定不同内存段的起始地址)。

type.txtbuild升级包过程生成的,里面的值1代表FullOTA0代表DiffOTAandroid的上层的update流程中会check这个值。

scatter.txt也是build升级包过程生成的,里面的内容来自于/mediatek/misc/ota_scatter.txt。具体code可见脚本ota_from_target_files。而mediatek/misc/ota_scatter.txt是在build full ota时会产生。该文件主要用于在升级的时候check升级前后parition layout是否有改变。

SEC_VER.TXT是在编译时从alps\mediatek\custom\$PROJECT\security\recoverycopy过来的,用于在打开SUPPORT_SBOOT_UPDATE之后会使用,具体可以参考[FAQ05739] SD或者OTA升级secutiry devicenon-security device的区别。

./mk new时,会执行ptgen,执行ptgen会依赖OTA_SCATTER_FILE,见mediatek/build/libs/pregen.mk218,然后再build/tools/makeMtk.mk中的142以及 692会生成ota_scatter.txt

2.3  OTA升级包制作工程分析

升级包有整包与差分包之分。顾名思义,所谓整包即包含整个system分区中的数据文件;而差分包则仅包含两个版本之间改动的部分。利用整包升级好比对电脑进行重作系统,格式化系统分区,并将新系统数据写入分区;而利用差分包升级不会格式化system分区,只是对其中部分存储段的内容进行重写。除升级包之外,制作过程中还会涉及到另一种zip包,代码中称之为8675-cota-target_files-xxx.zip,我称之为差分资源包。首先阐述下整包的制作过程。

2.3.1  整包的制作

系统经过整编后,执行makeotapackage命令,即可完成整包的制作,而此命令可分为两个阶段进行。首先执行./build/core/Makefile中的代码:

#-----------------------------------------------------------------
# OTA update package
 
name := $(TARGET_PRODUCT)
ifeq ($(TARGET_BUILD_TYPE),debug)
  name :=$(name)_debug
endif
name := $(name)-ota-$(FILE_NAME_TAG)
 
INTERNAL_OTA_PACKAGE_TARGET:= $(PRODUCT_OUT)/$(name).zip
$(INTERNAL_OTA_PACKAGE_TARGET): KEY_CERT_PAIR :=$(DEFAULT_KEY_CERT_PAIR)
$(INTERNAL_OTA_PACKAGE_TARGET):$(BUILT_TARGET_FILES_PACKAGE) $(OTATOOLS)
        @echo"Package OTA: $@"
        $(hide) ./build/tools/releasetools/ota_from_target_files-v \
           -n \
           -p$(HOST_OUT) \
           -k$(KEY_CERT_PAIR) \
          $(ota_extra_flag) \
          $(BUILT_TARGET_FILES_PACKAGE) $@
.PHONY: otapackage
otapackage: $(INTERNAL_OTA_PACKAGE_TARGET)
#-----------------------------------------------------------------

代码段1 make otapackage目标代码

如上代码是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所完成的功能全是通过这两个目标文件和执行的命令完成的,我们将分别对这三个关键点进行分析。

a)     $(OTATOOLS)

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

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)  


可以看出变量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目录,这意味着我们可以从此目录下找到上述工具,并为我们所用。

b)        $(BUILT_TARGET_FILES_PACKAGE)

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

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_
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值