2023年8月3日发(作者:)

linux给zip刷机包签名,如何打包安卓⼿机Zip升级包?如何签名?不换Recovery。。。满意答案dwhu8l2gph9推荐于 2017.10.09采纳率:48% 等级:13已帮助:5931⼈通过分析包在具体Android系统升级的过程,来理解Android系统中Recovery模式服务的⼯作原理。我们先从包的制作开始,然后是Android系统的启动模式分析,Recovery⼯作原理,如何从我们上层开始选择system update到重启到Recovery服务,以及在Recovery服务中具体怎样处理包升级的,我们的安装脚本updater-script怎样被解析并执⾏的等⼀系列问题。分析过程中所⽤的Android源码是gingerbread0919(tcc88xx开发板标配的),测试开发板是tcc88xx。⼀、 包的⽬录结构|----|----system/|----recovery/`|----recovery-from-boot.p`|----etc/`|----|---META-INF/`|`|`|`|----com/`|----google/`|----android/`|----update-binary`|----updater-script`|----android/`|----metadata⼆、 包⽬录结构详解以上是我们⽤命令make otapackage 制作的包的标准⽬录结构。1、是更新boot分区所需要的⽂件。这个主要包括kernel+ramdisk。2、system/⽬录的内容在升级后会放在系统的system分区。主要⽤来更新系统的⼀些应⽤或则应⽤会⽤到的⼀些库等等。可以将Android源码编译out/target/product/tcc8800/system/中的所有⽂件拷贝到这个⽬录来代替。3、recovery/⽬录中的recovery-from-boot.p是和的补丁(patch),主要⽤来更新recovery分区,其中etc/⽬录下的是更新脚本。4、update-binary是⼀个⼆进制⽂件,相当于⼀个脚本解释器,能够识别updater-script中描述的操作。该⽂件在Android源码编译后out/target/product/tcc8800/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、包的签名:更新包在制作完成后需要对其签名,否则在升级时会出现认证失败的错误提⽰。⽽且签名要使⽤和⽬标板⼀致的加密公钥。加密公钥及加密需要的三个⽂件在Android源码编译后⽣成的具体路径为:out/host/linux-x86/framework/ld/target/product/security/ld/target/product/security/8 。我们⽤命令make otapackage制作⽣成的包是已签过名的,如果⾃⼰做包时必须⼿动对其签名。具体的加密⽅法:$ java –jar gingerbread/out/host/linux/framework/ –wgingerbread/build/target/product/security/ gingerbread/build/target/product/security/ update_以上命令在包所在的路径下执⾏,其中 以及8⽂件的引⽤使⽤绝对路径。是我们已经打好的包,update_包是命令执⾏完⽣成的已经签过名的包。9、:这个manifest⽂件定义了与包的组成结构相关的数据。类似Android应⽤的⽂件。10、:与签名⽂件相关联的签名程序块⽂件,它存储了⽤于签名JAR⽂件的公共签名。11、:这是JAR⽂件的签名⽂件,其中前缀CERT代表签名者。另外,在具体升级时,对包检查时⼤致会分三步:①检验SF⽂件与RSA⽂件是否匹配。②检验与签名⽂件中的digest是否⼀致。③检验包中的⽂件与MANIFEST中所描述的是否⼀致。三、 Android升级包的⽣成过程分析1) 对于包的制作有两种⽅式,即⼿动制作和命令⽣成。第⼀种⼿动制作:即按照的⽬录结构⼿动创建我们需要的⽬录。然后将对应的⽂件拷贝到相应的⽬录下,⽐如我们向系统中新加⼀个应⽤程序。可以将新增的应⽤拷贝到我们新建的update/system/app/下(system⽬录是事先拷贝编译源码后⽣成的system⽬录),打包并签名后,拷贝到SD卡就可以使⽤了。这种⽅式在实际的tcc8800开发板中未测试成功。签名部分未通过,可能与具体的开发板相关。第⼆种制作⽅式:命令制作。Android源码系统中为我们提供了制作刷机包的命令,即make otapackage。该命令在编译源码完成后并在源码根⽬录下执⾏。 具体操作⽅式:在源码根⽬录下执⾏①$ . build/。②$ lunch 然后选择你需要的配置(如17)。③$ make otapackage。在编译完源码后最好再执⾏⼀遍上⾯的①、②步防⽌执⾏③时出现未找到对应规则的错误提⽰。命令执⾏完成后⽣成的升级包所在位置在out/target/product/full_tcc8800_evm_target_将这个包重新命名为,并拷贝到SD卡中即可使⽤。这种⽅式(即完全升级)在tcc8800开发板中已测试成功。2) 使⽤make otapackage命令⽣成的过程分析。在源码根⽬录下执⾏make otapackage命令⽣成包主要分为两步,第⼀步是根据Makefile执⾏编译⽣成⼀个update原包(zip格式)。第⼆步是运⾏⼀个python脚本,并以上⼀步准备的zip包作为输⼊,最终⽣成我们需要的升级包。下⾯进⼀步分析这两个过程。第⼀步:编译Makefile。对应的Makefile⽂件所在位置:build/core/Makefile。从该⽂件的884⾏(tcc8800,gingerbread0919)开始会⽣成⼀个zip包,这个包最后会⽤来制作OTA package 或者filesystem image。先将这部分的对应的Makefile贴出来如下:[python] view plaincopyprint?# -----------------------------------------------------------------# 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.#根据上⾯的Makefile可以分析这个包的⽣成过程:⾸先创建⼀个root_zip根⽬录,并依次在此⽬录下创建所需要的如下其他⽬录①创建RECOVERY⽬录,并填充该⽬录的内容,包括kernel的镜像和recovery根⽂件系统的镜像。此⽬录最终⽤于⽣成。②创建并填充BOOT⽬录。包含kernel和cmdline以及pagesize⼤⼩等,该⽬录最终⽤来⽣成。③向SYSTEM⽬录填充system image。④向DATA填充data image。⑤⽤于⽣成OTA package包所需要的额外的内容。主要包括⼀些bin命令。⑥创建META⽬录并向该⽬录下添加⼀些⽂本⽂件,如(描述apk⽂件⽤到的认证证书),misc_(描述Flash内存的块⼤⼩以及boot、recovery、system、userdata等分区的⼤⼩信息)。⑦使⽤保留连接选项压缩我们在上⾯获得的root_zip⽬录。⑧使⽤fs_config(build/tools/fs_config)配置上⾯的zip包内所有的系统⽂件(system/下各⽬录、⽂件)的权限属主等信息。fs_config包含了⼀个头⽂件#include“private/android_filesystem_config.h”。在这个头⽂件中以硬编码的⽅式设定了system⽬录下各⽂件的权限、属主。执⾏完配置后会将配置后的信息以⽂本⽅式输出 到META/filesystem_中。并再⼀次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包。⼆ 下⾯我们分析ota_from_target_files这个python脚本是怎样⽣成最终zip包的。先讲这个脚本的代码贴出来如下:[python] view plaincopyprint?import sysif sion < 0x02040000:print >> , "Python 2.4 or newer is required."(1)主函数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。⑥⾄此⼀个完整的升级包就⽣成了。⽣成位置在:out/target/product/tcc8800/full_tcc8800_。将升级包拷贝到SD卡中就可以⽤来升级了。四、 Android OTA增量包的⽣成在上⾯的过程中⽣成的升级包是全部系统的升级包。⼤⼩有80M多。这对⼿机⽤户来说,⽤来升级的流量是很⼤的。⽽且在实际升级中,我们只希望能够升级我们改变的那部分内容。这就需要使⽤增量包来升级。⽣成增量包的过程也需要上⽂中提到的ota_from_target_的参与。下⾯是制作增量包的过程。① 在源码根⽬录下依次执⾏下列命令$ . build/$ lunch 选择17$ make$ make otapackage执⾏上⾯的命令后会在out/target/product/tcc8800/下⽣成我们第⼀个系统升级包。我们先将其命名为② 在源码中修改我们需要改变的部分,⽐如修改内核配置,增加新的驱动等等。修改后再⼀次执⾏上⾯的命令。就会⽣成第⼆个我们修改后⽣成的升级包。将 其命名为。③ 在上⽂中我们看了ota_from_target_脚本的使⽤帮助,其中选项-i就是⽤来⽣成差分增量包的。使⽤⽅法是以上⾯的 和包作为输⼊,以包作 为输出。⽣成的就是我们最后需要的增量包。具体使⽤⽅式是:将上述两个包拷贝到源码根⽬录下,然后执⾏下⾯的命令。$ ./build/tools/releasetools/ota_from_target_files -i 。在执⾏上述命令时会出现未找到recovery_api_version的错误。原因是在执⾏上⾯的脚本时如果使⽤选项i则会调⽤WriteIncrementalOTAPackage会从A包和B包中的META⽬录下搜索misc_来读取recovery_api_version的值。但是在执⾏make otapackage命令时⽣成的包中没有这个⽬录更没有这个⽂档。此时我们就需要使⽤执⾏make otapackage⽣成的原始的zip包。这个包的位置在out/target/product/tcc8800/obj/PACKAGING/target_files_intermediates/⽬录下,它是在⽤命令make otapackage之后的中间⽣产物,是最原始的升级包。我们将两次编译的⽣成的包分别重命名为和,并拷贝到SD卡根⽬录下重复执⾏上⾯的命令:$ ./build/tools/releasetools/ota_form_target_files -i 。在上述命令即将执⾏完毕时,在device/telechips/common/会调⽤IncrementalOTA_InstallEnd,在这个函数中读取包中的RADIO/。⽽包中是没有这个⽬录和的。所以执⾏失败,未能⽣成对应的。可能与我们未修改bootloader(升级firmware)有关。此问题在下⼀篇博客已经解决。制作增量包失败的原因,以及解决⽅案。Android系统Recovery⼯作原理之使⽤升级过程分析(⼆)---差分包问题的解决在上⼀篇末尾提到的⽣成差分包时出现的问题,现已解决,由于最近⽐较忙,相隔的时间也⽐较长,所以单列⼀个篇幅提⽰⼤家。这个问题居然是源码中的问题,可能你已经制作成功了,不过我的这个问题确实是源码中的⼀个问题,不知道是不是⼀个bug,下⽂会具体分析!⼀、⽣成OTA增量包失败的解决⽅案在上⼀篇中末尾使⽤ota_from_target_files脚本制作增量包时失败,我们先将出现的错误贴出来。在执⾏这个脚本的最后读取input_zip中RADIO/时出现错误,显⽰DeviceSpecifiParams这个对象中没有input_zip属性。我们先从脚本中出现错误的调⽤函数中开始查找。出现错误的调⽤地⽅是在函WriteIncrementalOTAPackage(443⾏)中的device_entalOTA_InstallEnd(),其位于WriteIncrementalOTAPackage()中的末尾。进⼀步跟踪源码发现,这是⼀个回调函数,他的具体执⾏⽅法位于源码中/device/telechips/common/脚本中的IncrementalOTA_InstallEnd()函数。下⾯就分析这个函数的作⽤。脚本中的两个函数FullOTA_InstallEnd()和IncrementalOTA_InstallEnd()的作⽤都是从输⼊包中读取RADIO/下的⽂件写到输出包中,同时⽣成安装时执⾏脚本的那部分命令。只不过⼀个是直接将输⼊包中的镜像写到输出包中,⼀个是先⽐较target_zip和source_zip中的是否不同(使⽤选项-i⽣成差分包时),然后将新的镜像写⼊输出包中。下⾯先将这个函数(位于/device/telechips/common/)的具体实现贴出来:我们的实际情况是,在⽤命令make otapackage时⽣成的包中是没有这个RADIO⽬录下的镜像⽂件(因为这部分更新已被屏蔽掉了)。但是这个函数中对于从包中未读取到⽂件的情况是有错误处理的,即返回。所以我们要从 出现的实际错误中寻找问题的原由。真正出现错误的地⽅是:target_bootloader=_(“RADIO/”)。出现错误的原因是:AttributeError:‘DeviceSpecificParams’object has no attribute ‘input_zip’,提⽰我们DeviceSpecificParams对象没有input_zip这个属性。⼆、updater-script脚本执⾏流程分析:先看⼀下在测试过程中⽤命令make otapackage⽣成的升级脚本如下:[python] view plaincopyprint?assert(!less_than_int(1331176658, getprop("")));assert(getprop("") == "tcc8800" ||下⾯分析下这个脚本的执⾏过程:①⽐较时间戳:如果升级包较旧则终⽌脚本的执⾏。②匹配设备信息:如果和当前的设备信息不⼀致,则停⽌脚本的执⾏。③显⽰进度条:如果以上两步匹配则开始显⽰升级进度条。④格式化system分区并挂载。⑤提取包中的recovery以及system⽬录下的内容到系统的/system下。⑥为/system/bin/下的命令⽂件建⽴符号连接。⑦设置/system/下⽬录以及⽂件的属性。⑧将包中的提取到/tmp/。⑨将/tmp/镜像⽂件写⼊到boot分区。⑩完成后卸载/system。三、总结以上的九篇着重分析了Android系统中Recovery模式中的⼀种,即我们做好的包在系统更新时所⾛过的流程。其核⼼部分就是Recovery服务的⼯作原理。其他两种FACTORY RESET、ENCRYPTED FILE SYSTEM ENABLE/DISABLE与OTA INSTALL是相通的。重点是要理解Recovery服务的⼯作原理。另外详细分析其升级过程,对于我们在实际升级时,可以根据我们的需要做出相应的修改。11分享举报

2023年8月3日发(作者:)

linux给zip刷机包签名,如何打包安卓⼿机Zip升级包?如何签名?不换Recovery。。。满意答案dwhu8l2gph9推荐于 2017.10.09采纳率:48% 等级:13已帮助:5931⼈通过分析包在具体Android系统升级的过程,来理解Android系统中Recovery模式服务的⼯作原理。我们先从包的制作开始,然后是Android系统的启动模式分析,Recovery⼯作原理,如何从我们上层开始选择system update到重启到Recovery服务,以及在Recovery服务中具体怎样处理包升级的,我们的安装脚本updater-script怎样被解析并执⾏的等⼀系列问题。分析过程中所⽤的Android源码是gingerbread0919(tcc88xx开发板标配的),测试开发板是tcc88xx。⼀、 包的⽬录结构|----|----system/|----recovery/`|----recovery-from-boot.p`|----etc/`|----|---META-INF/`|`|`|`|----com/`|----google/`|----android/`|----update-binary`|----updater-script`|----android/`|----metadata⼆、 包⽬录结构详解以上是我们⽤命令make otapackage 制作的包的标准⽬录结构。1、是更新boot分区所需要的⽂件。这个主要包括kernel+ramdisk。2、system/⽬录的内容在升级后会放在系统的system分区。主要⽤来更新系统的⼀些应⽤或则应⽤会⽤到的⼀些库等等。可以将Android源码编译out/target/product/tcc8800/system/中的所有⽂件拷贝到这个⽬录来代替。3、recovery/⽬录中的recovery-from-boot.p是和的补丁(patch),主要⽤来更新recovery分区,其中etc/⽬录下的是更新脚本。4、update-binary是⼀个⼆进制⽂件,相当于⼀个脚本解释器,能够识别updater-script中描述的操作。该⽂件在Android源码编译后out/target/product/tcc8800/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、包的签名:更新包在制作完成后需要对其签名,否则在升级时会出现认证失败的错误提⽰。⽽且签名要使⽤和⽬标板⼀致的加密公钥。加密公钥及加密需要的三个⽂件在Android源码编译后⽣成的具体路径为:out/host/linux-x86/framework/ld/target/product/security/ld/target/product/security/8 。我们⽤命令make otapackage制作⽣成的包是已签过名的,如果⾃⼰做包时必须⼿动对其签名。具体的加密⽅法:$ java –jar gingerbread/out/host/linux/framework/ –wgingerbread/build/target/product/security/ gingerbread/build/target/product/security/ update_以上命令在包所在的路径下执⾏,其中 以及8⽂件的引⽤使⽤绝对路径。是我们已经打好的包,update_包是命令执⾏完⽣成的已经签过名的包。9、:这个manifest⽂件定义了与包的组成结构相关的数据。类似Android应⽤的⽂件。10、:与签名⽂件相关联的签名程序块⽂件,它存储了⽤于签名JAR⽂件的公共签名。11、:这是JAR⽂件的签名⽂件,其中前缀CERT代表签名者。另外,在具体升级时,对包检查时⼤致会分三步:①检验SF⽂件与RSA⽂件是否匹配。②检验与签名⽂件中的digest是否⼀致。③检验包中的⽂件与MANIFEST中所描述的是否⼀致。三、 Android升级包的⽣成过程分析1) 对于包的制作有两种⽅式,即⼿动制作和命令⽣成。第⼀种⼿动制作:即按照的⽬录结构⼿动创建我们需要的⽬录。然后将对应的⽂件拷贝到相应的⽬录下,⽐如我们向系统中新加⼀个应⽤程序。可以将新增的应⽤拷贝到我们新建的update/system/app/下(system⽬录是事先拷贝编译源码后⽣成的system⽬录),打包并签名后,拷贝到SD卡就可以使⽤了。这种⽅式在实际的tcc8800开发板中未测试成功。签名部分未通过,可能与具体的开发板相关。第⼆种制作⽅式:命令制作。Android源码系统中为我们提供了制作刷机包的命令,即make otapackage。该命令在编译源码完成后并在源码根⽬录下执⾏。 具体操作⽅式:在源码根⽬录下执⾏①$ . build/。②$ lunch 然后选择你需要的配置(如17)。③$ make otapackage。在编译完源码后最好再执⾏⼀遍上⾯的①、②步防⽌执⾏③时出现未找到对应规则的错误提⽰。命令执⾏完成后⽣成的升级包所在位置在out/target/product/full_tcc8800_evm_target_将这个包重新命名为,并拷贝到SD卡中即可使⽤。这种⽅式(即完全升级)在tcc8800开发板中已测试成功。2) 使⽤make otapackage命令⽣成的过程分析。在源码根⽬录下执⾏make otapackage命令⽣成包主要分为两步,第⼀步是根据Makefile执⾏编译⽣成⼀个update原包(zip格式)。第⼆步是运⾏⼀个python脚本,并以上⼀步准备的zip包作为输⼊,最终⽣成我们需要的升级包。下⾯进⼀步分析这两个过程。第⼀步:编译Makefile。对应的Makefile⽂件所在位置:build/core/Makefile。从该⽂件的884⾏(tcc8800,gingerbread0919)开始会⽣成⼀个zip包,这个包最后会⽤来制作OTA package 或者filesystem image。先将这部分的对应的Makefile贴出来如下:[python] view plaincopyprint?# -----------------------------------------------------------------# 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.#根据上⾯的Makefile可以分析这个包的⽣成过程:⾸先创建⼀个root_zip根⽬录,并依次在此⽬录下创建所需要的如下其他⽬录①创建RECOVERY⽬录,并填充该⽬录的内容,包括kernel的镜像和recovery根⽂件系统的镜像。此⽬录最终⽤于⽣成。②创建并填充BOOT⽬录。包含kernel和cmdline以及pagesize⼤⼩等,该⽬录最终⽤来⽣成。③向SYSTEM⽬录填充system image。④向DATA填充data image。⑤⽤于⽣成OTA package包所需要的额外的内容。主要包括⼀些bin命令。⑥创建META⽬录并向该⽬录下添加⼀些⽂本⽂件,如(描述apk⽂件⽤到的认证证书),misc_(描述Flash内存的块⼤⼩以及boot、recovery、system、userdata等分区的⼤⼩信息)。⑦使⽤保留连接选项压缩我们在上⾯获得的root_zip⽬录。⑧使⽤fs_config(build/tools/fs_config)配置上⾯的zip包内所有的系统⽂件(system/下各⽬录、⽂件)的权限属主等信息。fs_config包含了⼀个头⽂件#include“private/android_filesystem_config.h”。在这个头⽂件中以硬编码的⽅式设定了system⽬录下各⽂件的权限、属主。执⾏完配置后会将配置后的信息以⽂本⽅式输出 到META/filesystem_中。并再⼀次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包。⼆ 下⾯我们分析ota_from_target_files这个python脚本是怎样⽣成最终zip包的。先讲这个脚本的代码贴出来如下:[python] view plaincopyprint?import sysif sion < 0x02040000:print >> , "Python 2.4 or newer is required."(1)主函数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。⑥⾄此⼀个完整的升级包就⽣成了。⽣成位置在:out/target/product/tcc8800/full_tcc8800_。将升级包拷贝到SD卡中就可以⽤来升级了。四、 Android OTA增量包的⽣成在上⾯的过程中⽣成的升级包是全部系统的升级包。⼤⼩有80M多。这对⼿机⽤户来说,⽤来升级的流量是很⼤的。⽽且在实际升级中,我们只希望能够升级我们改变的那部分内容。这就需要使⽤增量包来升级。⽣成增量包的过程也需要上⽂中提到的ota_from_target_的参与。下⾯是制作增量包的过程。① 在源码根⽬录下依次执⾏下列命令$ . build/$ lunch 选择17$ make$ make otapackage执⾏上⾯的命令后会在out/target/product/tcc8800/下⽣成我们第⼀个系统升级包。我们先将其命名为② 在源码中修改我们需要改变的部分,⽐如修改内核配置,增加新的驱动等等。修改后再⼀次执⾏上⾯的命令。就会⽣成第⼆个我们修改后⽣成的升级包。将 其命名为。③ 在上⽂中我们看了ota_from_target_脚本的使⽤帮助,其中选项-i就是⽤来⽣成差分增量包的。使⽤⽅法是以上⾯的 和包作为输⼊,以包作 为输出。⽣成的就是我们最后需要的增量包。具体使⽤⽅式是:将上述两个包拷贝到源码根⽬录下,然后执⾏下⾯的命令。$ ./build/tools/releasetools/ota_from_target_files -i 。在执⾏上述命令时会出现未找到recovery_api_version的错误。原因是在执⾏上⾯的脚本时如果使⽤选项i则会调⽤WriteIncrementalOTAPackage会从A包和B包中的META⽬录下搜索misc_来读取recovery_api_version的值。但是在执⾏make otapackage命令时⽣成的包中没有这个⽬录更没有这个⽂档。此时我们就需要使⽤执⾏make otapackage⽣成的原始的zip包。这个包的位置在out/target/product/tcc8800/obj/PACKAGING/target_files_intermediates/⽬录下,它是在⽤命令make otapackage之后的中间⽣产物,是最原始的升级包。我们将两次编译的⽣成的包分别重命名为和,并拷贝到SD卡根⽬录下重复执⾏上⾯的命令:$ ./build/tools/releasetools/ota_form_target_files -i 。在上述命令即将执⾏完毕时,在device/telechips/common/会调⽤IncrementalOTA_InstallEnd,在这个函数中读取包中的RADIO/。⽽包中是没有这个⽬录和的。所以执⾏失败,未能⽣成对应的。可能与我们未修改bootloader(升级firmware)有关。此问题在下⼀篇博客已经解决。制作增量包失败的原因,以及解决⽅案。Android系统Recovery⼯作原理之使⽤升级过程分析(⼆)---差分包问题的解决在上⼀篇末尾提到的⽣成差分包时出现的问题,现已解决,由于最近⽐较忙,相隔的时间也⽐较长,所以单列⼀个篇幅提⽰⼤家。这个问题居然是源码中的问题,可能你已经制作成功了,不过我的这个问题确实是源码中的⼀个问题,不知道是不是⼀个bug,下⽂会具体分析!⼀、⽣成OTA增量包失败的解决⽅案在上⼀篇中末尾使⽤ota_from_target_files脚本制作增量包时失败,我们先将出现的错误贴出来。在执⾏这个脚本的最后读取input_zip中RADIO/时出现错误,显⽰DeviceSpecifiParams这个对象中没有input_zip属性。我们先从脚本中出现错误的调⽤函数中开始查找。出现错误的调⽤地⽅是在函WriteIncrementalOTAPackage(443⾏)中的device_entalOTA_InstallEnd(),其位于WriteIncrementalOTAPackage()中的末尾。进⼀步跟踪源码发现,这是⼀个回调函数,他的具体执⾏⽅法位于源码中/device/telechips/common/脚本中的IncrementalOTA_InstallEnd()函数。下⾯就分析这个函数的作⽤。脚本中的两个函数FullOTA_InstallEnd()和IncrementalOTA_InstallEnd()的作⽤都是从输⼊包中读取RADIO/下的⽂件写到输出包中,同时⽣成安装时执⾏脚本的那部分命令。只不过⼀个是直接将输⼊包中的镜像写到输出包中,⼀个是先⽐较target_zip和source_zip中的是否不同(使⽤选项-i⽣成差分包时),然后将新的镜像写⼊输出包中。下⾯先将这个函数(位于/device/telechips/common/)的具体实现贴出来:我们的实际情况是,在⽤命令make otapackage时⽣成的包中是没有这个RADIO⽬录下的镜像⽂件(因为这部分更新已被屏蔽掉了)。但是这个函数中对于从包中未读取到⽂件的情况是有错误处理的,即返回。所以我们要从 出现的实际错误中寻找问题的原由。真正出现错误的地⽅是:target_bootloader=_(“RADIO/”)。出现错误的原因是:AttributeError:‘DeviceSpecificParams’object has no attribute ‘input_zip’,提⽰我们DeviceSpecificParams对象没有input_zip这个属性。⼆、updater-script脚本执⾏流程分析:先看⼀下在测试过程中⽤命令make otapackage⽣成的升级脚本如下:[python] view plaincopyprint?assert(!less_than_int(1331176658, getprop("")));assert(getprop("") == "tcc8800" ||下⾯分析下这个脚本的执⾏过程:①⽐较时间戳:如果升级包较旧则终⽌脚本的执⾏。②匹配设备信息:如果和当前的设备信息不⼀致,则停⽌脚本的执⾏。③显⽰进度条:如果以上两步匹配则开始显⽰升级进度条。④格式化system分区并挂载。⑤提取包中的recovery以及system⽬录下的内容到系统的/system下。⑥为/system/bin/下的命令⽂件建⽴符号连接。⑦设置/system/下⽬录以及⽂件的属性。⑧将包中的提取到/tmp/。⑨将/tmp/镜像⽂件写⼊到boot分区。⑩完成后卸载/system。三、总结以上的九篇着重分析了Android系统中Recovery模式中的⼀种,即我们做好的包在系统更新时所⾛过的流程。其核⼼部分就是Recovery服务的⼯作原理。其他两种FACTORY RESET、ENCRYPTED FILE SYSTEM ENABLE/DISABLE与OTA INSTALL是相通的。重点是要理解Recovery服务的⼯作原理。另外详细分析其升级过程,对于我们在实际升级时,可以根据我们的需要做出相应的修改。11分享举报