OTA升级中关于update.zip包的⼀些总结【转】
update.zip包整理
⼀、 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
⼆、
boot.img 包含kernel和ramdisk,⽤来更新boot分区所需要的⽂件
system 内容升级后放在系统的system分区,主要更新⼀些apk和so库
recovery/⽬录中的recovery-from-boot.p是boot.img和recovery.img的补丁(patch),主要⽤来更新recovery分区,其中etc/⽬录下的install-recovery.sh是更新脚本
update-binary是⼀个⼆进制⽂件,相当于⼀个脚本解释器,能够识别updater-script中的描述的操作,该⽂件在具体的更新包中名字由源码中bootable/recovery/install.c中的
ASSUMED_UPDATE_BINARY_NAME的值⽽定
updater-script:此⽂件是⼀个脚本⽂件,具体描述更新过程,在之前可以根据具体情况编写该脚本适应我们的具体需求,该⽂件的命名由源码中的bootable/recovery/
updater/updater.c⽂件中的SCRIPT_NAME的值⽽定
metadata⽂件是描述设备信息及环境变量的元数据,主要包括⼀些编译选项,签名公钥,时间戳以及设别型号等
uesrdata⽬录,⽤来更新系统中的⽤户数据部分,这部分内容在更新后会存放在系统的data⽬录下,但是在Android M后data分区默认加密,在OTA的时候不能挂载data分
区,所以不能进⾏更新
在update.zip包⽣成后需要对其进⾏签名,否则在升级时会出现认证失败的错误提⽰。⽽且签名要使⽤和⽬标版本⼀致的加密公钥。加密公钥以及加密所需的三个⽂件在Android源码编译后⽣成的具体路径为:
out/host/linux-x86/framework/signapk.jar
build/target/product/security/testkey.x509.pem
build/target/product/security/testkey.pk8
具体的加密⽅法:$ java -jar out/host/linux-x86/framework/signapk.jar -w build/traget/product/security/tesetkey.x509.pem
build/target/product/security/testkey.pk8 update.zip update_signed.zip
MANIFEST.MF :这个manifest⽂件定义了与包的组成结构相关的数据,类似Android应⽤的l⽂件
android11系统更新包下载CERT.RSA:与签名⽂件相关联的签名程序块⽂件,他存储了⽤于签名jar⽂件的公共签名
CERT.SF:这是jar⽂件的签名⽂件,其中前缀CERT代表签名者
在具体升级的时候,对update.zip包检查时⼤致会分成三步:1.检验SF⽂件与RSA⽂件是否匹配。2、检验MANIFEST.MF与签名⽂件中的digest是否⼀致。3.检验包中的⽂件与MANIFEST中所描述的是否⼀致。
三、Android升级包update.zip的⽣成过程分析
使⽤make otapackage命令⽣成update.zip的过程分析。
在源码根⽬录下执⾏make otapackage命令⽣成update.zip包主要分为两步,第⼀步是根据Makefile执⾏编译⽣成⼀个update原包(zip格式)。第⼆步是运⾏⼀个python脚本,并以上⼀步准备的zip包作为输⼊,最终⽣成我们需要的升级包。下⾯进⼀步分析这两个过程。(简单开说就是,⾸先⽣成cota包,在利⽤cota包⽣成差分包和整包)
第⼀步:编译Makefile。对应的Makefile⽂件所在位置:build/core/Makefile。从该⽂件会⽣成⼀个zip包,这个包最后会⽤来制作OTA package 或者filesystem image。
根据Makefile可以分析这个包的⽣成过程:
⾸先创建⼀个root_zip根⽬录,并依次在此⽬录下创建所需要的如下其他⽬录
①创建RECOVERY⽬录,并填充该⽬录的内容,包括kernel的镜像和recovery根⽂件系统的镜像。此⽬录最终⽤于⽣成recovery.img。
②创建并填充BOOT⽬录。包含kernel和cmdline以及pagesize⼤⼩等,该⽬录最终⽤来⽣成boot.img。
③向SYSTEM⽬录填充system image。
④向DATA填充data image。
⑤⽤于⽣成OTA package包所需要的额外的内容。主要包括⼀些bin命令。
⑥创建META⽬录并向该⽬录下添加⼀些⽂本⽂件,如(描述apk⽂件⽤到的认证证书),(描述Flash内存的块⼤⼩以及boot、recovery、system、userdata等分区的⼤⼩信息)。
⑦使⽤保留连接选项压缩我们在上⾯获得的root_zip⽬录。
⑧使⽤fs_config(build/tools/fs_config)配置上⾯的zip包内所有的系统⽂件(system/下各⽬录、⽂件)的权限属主等信息。fs_config包含
了⼀个头⽂件#include“private/android_filesystem_config.h”。在这个头⽂件中以硬编码的⽅式设定了sy
stem⽬录下各⽂件的权限、属主。执⾏完配置后会将配置后的信息以⽂本⽅式输出到META/中。并再⼀次zip压缩成我们最终需要的原始包。
第⼆步:上⾯的zip包只是⼀个编译过程中⽣成的原始包。这个原始zip包在实际的编译过程中有两个作⽤,⼀是⽤来⽣成OTA update升级包,⼆是⽤来⽣成系统镜像。在编译过程中若⽣成OTA update升级包时会调⽤(具体位置在Makefile的1037⾏到1058⾏)⼀个名为
ota_from_target_files的Python脚本,位置在/build/tools/releasetools/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命令帮助
下⾯我们分析ota_from_target_files这个python脚本是怎样⽣成最终zip包的。
主函数main是python的⼊⼝函数,我们从main函数开始看,⼤概看⼀下main函数(脚本最后)⾥的流程就能知道脚本的执⾏过程了。
①在main函数的开头,⾸先将⽤户设定的option选项存⼊OPTIONS变量中,它是⼀个python中的类。紧接着判断有没有额外的脚本,如果有就读⼊到OPTIONS变量中。
②解压缩输⼊的zip包,即我们在上⽂⽣成的原始zip包。然后判断是否⽤到device-specific extensions(设备扩展)如果⽤到,随即读⼊到OPTIONS变量中。
③判断是否签名,然后判断是否有新内容的增量源,有的话就解压该增量源包放⼊⼀个临时变量中(source_zip)。⾃此,所有的准备⼯作已完毕,随即会调⽤该脚本中最主要的函数WriteFullOTAPackage(input_zip,output_zip)
④ WriteFullOTAPackage函数的处理过程是先获得脚本的⽣成器。默认格式是edify。然后获得metadata元数据,此数据来⾄于Android的⼀些环境变量。然后获得设备配置参数⽐如api函数的版本。然后判断是否忽略时间戳。
⑤ WriteFullOTAPackage函数做完准备⼯作后就开始⽣成升级⽤的脚本⽂件(updater-script)了。⽣成脚本⽂件后将上⼀步获得的metadata元数据写⼊到输出包out_zip。
⑥⾄此⼀个完整的update.zip升级包就⽣成了。将升级包拷贝到SD卡中就可以⽤来升级了。
四、 Android OTA增量包update.zip的⽣成
在上⾯的过程中⽣成的update.zip升级包是全部系统的升级包,⽽在实际升级中,我们只希望能够升级我们改变的那部分内容。这就需要使⽤增量包来升级。⽣成增量包的过程也需要上⽂中提到的ota_from_target_files.py的参与。
下⾯是制作update.zip增量包的过程。
①在源码根⽬录下依次执⾏下列命令
$ . build/envsetup.sh
$ lunch XXX
$ make
$ make otapackage
执⾏上⾯的命令后会在out/target/product/tcc8800/下⽣成我们第⼀个系统升级包。我们先将其命名为A.zip
②在源码中修改我们需要改变的部分,⽐如修改内核配置,增加新的驱动等等。修改后再⼀次执⾏上⾯的命令。就会⽣成第⼆个我们修改后⽣成的update.zip升级包。将其命名为B.zip。
③在上⽂中我们看了ota_from_target_files.py脚本的使⽤帮助,其中选项-i就是⽤来⽣成差分增量包的。使⽤⽅法是以上⾯的A.zip 和
B.zip包作为输⼊,以update.zip包作为输出。⽣成的update.zip就是我们最后需要的增量包。
具体使⽤⽅式是:将上述两个包拷贝到源码根⽬录下,然后执⾏下⾯的命令。
$ ./build/tools/releasetools/ota_from_target_files -i A.zip B.zip update.zip。(还可以加⼊其他参数,例如-x,-k,-p等等)在执⾏上述命令时会出现未到recovery_api_version的错误。原因是在执⾏上⾯的脚本时如果使⽤选项i则会调⽤WriteIncrementalOTAPackage会从A包和B包中的META⽬录下搜索来读取recovery_api_version的值。但是在执⾏make
otapackage命令时⽣成的update.zip包中没有这个⽬录更没有这个⽂档。
此时我们就需要使⽤执⾏make otapackage⽣成的原始的zip包。这个包的位置在
out/target/product/XX/obj/PACKAGING/target_files_intermediates/⽬录下(cota包),它是在⽤命令make otapackage之后的中间⽣产物,是最原始的升级包。我们将两次编译的⽣成的包分别重命名为A.zip和B.zip,并拷贝到SD卡根⽬录下重复执⾏上⾯的命令:
$ ./build/tools/releasetools/ota_form_target_files -i A.zip B.zip update.zip。
另:
⽣成差分包调⽤的是⽂件./build/tools/releasetools/ota_from_target_files中的WriteIncrementalOTA⽅法,调⽤时需要将两个版本的差分资源包作为参数传进来,形如:
./build/tools/releasetools/ota_from_target_files –n –i ota_v1.zip ota_v2.zip update.zip
其中,参数n表⽰忽略时间戳;i表⽰⽣成增量包(即差分包);ota_v1.zip与ota_v2.zip分别代表前后两个版本的差分资源包;⽽update.zip 则表⽰最终⽣成的差分包。
WriteIncrementalOTA函数会计算输⼊的两个差分资源包中版本的差异,并将其写⼊到差分包中;同时,将updater及⽣成脚本⽂件udpate-script添加到升级包中。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论