Android系统Recovery工作原理之使用update.zip升级过程分析(二)---u...
2019獨角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
?Android系統(tǒng)Recovery工作原理之使用update.zip升級過程分析(二)---update.zip差分包問題的解決? ? ? ?在上一篇末尾提到的生成差分包時出現(xiàn)的問題,現(xiàn)已解決,由于最近比較忙,相隔的時間也比較長,所以單列一個篇幅提示大家。這個問題居然是源碼中的問題,可能你已經(jīng)制作成功了,不過我的這個問題確實是源碼中的一個問題,不知道是不是一個bug,下文會具體分析!
一、生成OTA增量包失敗的解決方案
? ? ? ? ? ?在上一篇中末尾使用ota_from_target_files腳本制作update.zip增量包時失敗,我們先將出現(xiàn)的錯誤貼出來。
? ? ? ? ? ? ? ? ?
?
? ? ? ? ? ? ??在執(zhí)行這個腳本的最后讀取input_zip中RADIO/bootloader.img時出現(xiàn)錯誤,顯示DeviceSpecifiParams這個對象中沒有input_zip屬性。
? ? ? ? ?我們先從腳本中出現(xiàn)錯誤的調(diào)用函數(shù)中開始查找。出現(xiàn)錯誤的調(diào)用地方是在函WriteIncrementalOTAPackage(443行)中的device_specific.IncrementalOTA_InstallEnd(),其位于WriteIncrementalOTAPackage()中的末尾。進(jìn)一步跟蹤源碼發(fā)現(xiàn),這是一個回調(diào)函數(shù),他的具體執(zhí)行方法位于源碼中/device/telechips/common/releasetools.py腳本中的IncrementalOTA_InstallEnd()函數(shù)。下面就分析這個函數(shù)的作用。
? ? ? ? ? releasetools.py腳本中的兩個函數(shù)FullOTA_InstallEnd()和IncrementalOTA_InstallEnd()的作用都是從輸入包中讀取RADIO/下的bootloader.img文件寫到輸出包中,同時生成安裝bootloader.img時執(zhí)行腳本的那部分命令。只不過一個是直接將輸入包中的bootloader.img鏡像寫到輸出包中,一個是先比較target_zip和source_zip中的bootloader.img是否不同(使用選項-i生成差分包時),然后將新的鏡像寫入輸出包中。下面先將這個函數(shù)(位于/device/telechips/common/releasetools.py)的具體實現(xiàn)貼出來:
? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ?我們的實際情況是,在用命令make otapackage時生成的包中是沒有這個RADIO目錄下的bootloader.img鏡像文件(因為這部分更新已被屏蔽掉了)。但是這個函數(shù)中對于從包中未讀取到bootloader.img文件的情況是有錯誤處理的,即返回。所以我們要從??出現(xiàn)的實際錯誤中尋找問題的原由。
? ? ? ? ?真正出現(xiàn)錯誤的地方是:
? ? ? ? ? target_bootloader=info.input_zip.read(“RADIO/bootloader.img”)。
? ? ? ? ?出現(xiàn)錯誤的原因是:AttributeError:‘DeviceSpecificParams’object has no attribute ?‘input_zip’,提示我們DeviceSpecificParams對象沒有input_zip這個屬性。
? ? ? ? ?在用ota_from_target_files腳本制作差分包時使用了選項-i,并且只有這種情況有三個參數(shù),即target_zip 、source_zip、 out_zip。而出現(xiàn)錯誤的地方是target_bootloader=info.input_zip_read(“RADIO/bootloader.img”),它使用的是input_zip,我們要懷疑這個地方是不是使用錯了,而應(yīng)該使用info.target_zip.read()。下面可以證實一下我們的猜測。
? ? ? ? ?從ota_from_target_files腳本中WriteFullOTAPackage()和WriteIncrementalOTAPackage這兩個函數(shù)(分別用來生成全包和差分包)可以發(fā)現(xiàn),在他們的開始部分都對device_specific進(jìn)行了賦值。其中WriteFullOTAPackage()對應(yīng)的參數(shù)是input_zip和out_zip,而WriteIncrementalOTAPackage對應(yīng)的是target_zip,source_zip,out_zip,我們可以看一下在WriteIncrementalOTAPackage函數(shù)中這部分的具體實現(xiàn):
? ? ? ? ? ? ? ? ??? ? ? ? ? ? 從上圖可以發(fā)現(xiàn),在WriteIncrementalOTAPackage函數(shù)對DeviceSpecificParams對象進(jìn)行初始化時確實使用的是target_zip而不是input_zip。而在releasetools.py腳本中使用的卻是info.input_zip.read(),所以才會出現(xiàn)DeviceSpecificParams對象沒有input_zip這個屬性。由此我們找到了問題的所在(這是不是源碼中的一個Bug?)。
? ? ? ? 將releasetools.py腳本IncrementalOTA_InstallEnd(info)函數(shù)中的 target_bootloader=info.input_zip.
read(“RADIO/bootloader.img”)為:target_bootloader=info.target_zip.read(“RADIO/bootloader.img”),然后重新執(zhí)行上面提到的制作差分包命令。就生成了我們需要的差分包update.zip。
二、??????????差分包update.zip的更新測試? ? ?
? ? ? ? ? ? ? ??在上面制作差分包腳本命令中,生成差分包的原理是,參照第一個參數(shù)(target_zip),將第二個參數(shù)(source_zip)中不同的部分輸出到第三個參數(shù)(output_zip)中。其中target_zip與source_zip的先后順序不同,產(chǎn)生的差分包也將不同。
? ? ? ? ? 在實際的測試過程中,我們的增量包要刪除之前添加的一個應(yīng)用(在使用update.zip全包升級時增加的),其他的部分如內(nèi)核都沒有改動,所以生成的差分包很簡單,只有META-INF這個文件夾。主要的不同都體現(xiàn)在updater-script腳本中,其中的#----start make changes? here----之后的部分就是做出改變的部分,最主要的腳本命令是:?delete(“/system/app/CheckUpdateAll.apk” , “/system/recovery.img”);在具體更新時它將刪除CheckUpdateAll.apk這個應(yīng)用。
? ? ? ? ? 為了大家參考,還是把這個差分包的升級腳本貼出來,其對應(yīng)的完全升級的腳本在第九篇已貼出:
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系統(tǒng)為依據(jù),也就是更新之前的開發(fā)板系統(tǒng)是用target_zip包升級后的系統(tǒng)。否則會更新就會失敗,因為在更新時會從系統(tǒng)對應(yīng)的目錄下讀取設(shè)備以及時間戳等信息(updater-script腳本一開始的部分),進(jìn)行匹配正確后才進(jìn)行下一步的安裝。
???????? 所有準(zhǔn)備都完成后,將我們制作的差分包放到SD卡中,在Settings-->About Phone-->System Update-->Installed From SDCARD執(zhí)行更新。最后更新完成并重啟后,我們會發(fā)現(xiàn)之前的CheckUpdateAll.apk被成功刪掉了,大功告成!
? ? ? ? 至此終于將update.zip包以及其對應(yīng)的差分包制作成功了,下面的文章開始具體分析制作的update.zip包在實際的更新中所走的過程!
轉(zhuǎn)載于:https://my.oschina.net/u/572562/blog/63835
總結(jié)
以上是生活随笔為你收集整理的Android系统Recovery工作原理之使用update.zip升级过程分析(二)---u...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何进行防SQL注入?
- 下一篇: 第一个Android工程HelloAnd