Android系统Recovery工做原理之使用update.zip升级过程分析(二)---u...

 Android系统Recovery工做原理之使用update.zip升级过程分析(二)---update.zip差分包问题的解决

       在上一篇末尾提到的生成差分包时出现的问题,现已解决,因为最近比较忙,相隔的时间也比较长,因此单列一个篇幅提示你们。这个问题竟然是源码中的问题,可能你已经制做成功了,不过个人这个问题确实是源码中的一个问题,不知道是否是一个bug,下文会具体分析!app

1、生成OTA增量包失败的解决方案tcp

           在上一篇中末尾使用ota_from_target_files脚本制做update.zip增量包时失败,咱们先将出现的错误贴出来函数

                 

 

              在执行这个脚本的最后读取input_zip中RADIO/bootloader.img时出现错误,显示DeviceSpecifiParams这个对象中没有input_zip属性。测试

         咱们先从脚本中出现错误的调用函数中开始查找。出现错误的调用地方是在函WriteIncrementalOTAPackage(443行)中的device_specific.IncrementalOTA_InstallEnd(),其位于WriteIncrementalOTAPackage()中的末尾。进一步跟踪源码发现,这是一个回调函数,他的具体执行方法位于源码中/device/telechips/common/releasetools.py脚本中的IncrementalOTA_InstallEnd()函数。下面就分析这个函数的做用。ui

          releasetools.py脚本中的两个函数FullOTA_InstallEnd()和IncrementalOTA_InstallEnd()的做用都是从输入包中读取RADIO/下的bootloader.img文件写到输出包中,同时生成安装bootloader.img时执行脚本的那部分命令。只不过一个是直接将输入包中的bootloader.img镜像写到输出包中,一个是先比较target_zip和source_zip中的bootloader.img是否不一样(使用选项-i生成差分包时),而后将新的镜像写入输出包中。下面先将这个函数(位于/device/telechips/common/releasetools.py)的具体实现贴出来:spa

                    

               咱们的实际状况是,在用命令make otapackage时生成的包中是没有这个RADIO目录下的bootloader.img镜像文件(由于这部分更新已被屏蔽掉了)。可是这个函数中对于从包中未读取到bootloader.img文件的状况是有错误处理的,即返回。因此咱们要从  出现的实际错误中寻找问题的起因。.net

         真正出现错误的地方是:对象

          target_bootloader=info.input_zip.read(“RADIO/bootloader.img”)。blog

         出现错误的缘由是:AttributeError:‘DeviceSpecificParams’object has no attribute  ‘input_zip’,提示咱们DeviceSpecificParams对象没有input_zip这个属性。ip

         在用ota_from_target_files脚本制做差分包时使用了选项-i,而且只有这种状况有三个参数,即target_zip 、source_zip、 out_zip。而出现错误的地方是target_bootloader=info.input_zip_read(“RADIO/bootloader.img”),它使用的是input_zip,咱们要怀疑这个地方是否是使用错了,而应该使用info.target_zip.read()。下面能够证明一下咱们的猜想。

         从ota_from_target_files脚本中WriteFullOTAPackage()和WriteIncrementalOTAPackage这两个函数(分别用来生成全包和差分包)能够发现,在他们的开始部分都对device_specific进行了赋值。其中WriteFullOTAPackage()对应的参数是input_zip和out_zip,而WriteIncrementalOTAPackage对应的是target_zip,source_zip,out_zip,咱们能够看一下在WriteIncrementalOTAPackage函数中这部分的具体实现:

                  

            从上图能够发现,在WriteIncrementalOTAPackage函数对DeviceSpecificParams对象进行初始化时确实使用的是target_zip而不是input_zip。而在releasetools.py脚本中使用的倒是info.input_zip.read(),因此才会出现DeviceSpecificParams对象没有input_zip这个属性。由此咱们找到了问题的所在(这是否是源码中的一个Bug?)。

        将releasetools.py脚本IncrementalOTA_InstallEnd(info)函数中的 target_bootloader=info.input_zip.

read(“RADIO/bootloader.img”)为:target_bootloader=info.target_zip.read(“RADIO/bootloader.img”),而后从新执行上面提到的制做差分包命令。就生成了咱们须要的差分包update.zip。

2、          差分包update.zip的更新测试     

                在上面制做差分包脚本命令中,生成差分包的原理是,参照第一个参数(target_zip),将第二个参数(source_zip)中不一样的部分输出到第三个参数(output_zip)中。其中target_zip与source_zip的前后顺序不一样,产生的差分包也将不一样。

          在实际的测试过程当中,咱们的增量包要删除以前添加的一个应用(在使用update.zip全包升级时增长的),其余的部分如内核都没有改动,因此生成的差分包很简单,只有META-INF这个文件夹。主要的不一样都体如今updater-script脚本中,其中的#----start make changes  here----以后的部分就是作出改变的部分,最主要的脚本命令是: delete(“/system/app/CheckUpdateAll.apk” , “/system/recovery.img”);在具体更新时它将删除CheckUpdateAll.apk这个应用。

          为了你们参考,仍是把这个差分包的升级脚本贴出来,其对应的彻底升级的脚本在第九篇已贴出

mount("yaffs2", "MTD", "system", "/system"); assert(file_getprop("/system/build.prop", "ro.build.fingerprint") == "telechips/full_tcc8800_evm/tcc8800:2.3.5/GRJ90/eng.mumu.20120309.100232:eng/test-keys" || file_getprop("/system/build.prop", "ro.build.fingerprint") == "telechips/full_tcc8800_evm/tcc8800:2.3.5/GRJ90/eng.mumu.20120309.100232:eng/test-keys"); assert(getprop("ro.product.device") == "tcc8800" || getprop("ro.build.product") == "tcc8800"); ui_print("Verifying current system..."); show_progress(0.100000, 0); # ---- start making changes here ---- ui_print("Removing unneeded files..."); delete("/system/app/CheckUpdateAll.apk", "/system/recovery.img"); show_progress(0.800000, 0); ui_print("Patching system files..."); show_progress(0.100000, 10); ui_print("Symlinks and permissions..."); set_perm_recursive(0, 0, 0755, 0644, "/system"); set_perm_recursive(0, 2000, 0755, 0755, "/system/bin"); set_perm(0, 3003, 02750, "/system/bin/netcfg"); set_perm(0, 3004, 02755, "/system/bin/ping"); set_perm(0, 2000, 06750, "/system/bin/run-as"); set_perm_recursive(1002, 1002, 0755, 0440, "/system/etc/bluetooth"); set_perm(0, 0, 0755, "/system/etc/bluetooth"); set_perm(1000, 1000, 0640, "/system/etc/bluetooth/auto_pairing.conf"); set_perm(3002, 3002, 0444, "/system/etc/bluetooth/blacklist.conf"); set_perm(1002, 1002, 0440, "/system/etc/dbus.conf"); set_perm(1014, 2000, 0550, "/system/etc/dhcpcd/dhcpcd-run-hooks"); set_perm(0, 2000, 0550, "/system/etc/init.goldfish.sh"); set_perm_recursive(0, 0, 0755, 0555, "/system/etc/ppp"); set_perm_recursive(0, 2000, 0755, 0755, "/system/xbin"); set_perm(0, 0, 06755, "/system/xbin/librank"); set_perm(0, 0, 06755, "/system/xbin/procmem"); set_perm(0, 0, 06755, "/system/xbin/procrank"); set_perm(0, 0, 06755, "/system/xbin/su"); set_perm(0, 0, 06755, "/system/xbin/tcpdump"); unmount("/system");

         在作更新测试时,咱们要以target_zip系统为依据,也就是更新以前的开发板系统是用target_zip包升级后的系统。不然会更新就会失败,由于在更新时会从系统对应的目录下读取设备以及时间戳等信息(updater-script脚本一开始的部分),进行匹配正确后才进行下一步的安装。

         全部准备都完成后,将咱们制做的差分包放到SD卡中,在Settings-->About Phone-->System Update-->Installed From SDCARD执行更新。最后更新完成并重启后,咱们会发现以前的CheckUpdateAll.apk被成功删掉了,大功告成!

        至此终于将update.zip包以及其对应的差分包制做成功了,下面的文章开始具体分析制做的update.zip包在实际的更新中所走的过程!

相关文章
相关标签/搜索