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包在實際的更新中所走的過程!

相關文章
相關標籤/搜索