1. 程式人生 > >OTA升級包制作工具處理過程分析

OTA升級包制作工具處理過程分析

host ext updater 解析 misc dsm 應該 增量升級 預處理


http://blog.csdn.net/ly890700/article/details/56048815

1、概述
OTA升級包制作工具是一個用python實現的命令行工具。工具位於source_root/ \build\tools\releasetools目錄下,入口文件是ota_from_target_files。此工具可對編譯生成的源或目標軟件版本包進行處理,生成最終的OAT完整升級包(默認),或通過參數-i控制,生成OTA增量升級包(差分包)。
源或目標軟件版本包的來源是通過向版本編譯配置文件main.mk中添加編譯OTA版本編譯選項$(INTERNAL_OTA_PACKAGE_TARGET)來完成的。這個不在本文檔中不做詳細說明。
2、運行環境
工具直接提供了python源碼,需要在執行環境上安裝python解析器(python運行環境,類似於java的JRE)。工具對python的版本做了要求,需要在2.4或更高以上的python版本上執行,否則可能會在處理過程中出錯。
3、命令行參數
工具的命令行參數因版本不同有微小的變化,現列舉一些常見參數說明:
-b (--board_config) <file>
在代碼中用pass處理這一參數匹配,不做處理。
-k (--package_key) <key>
指定簽名用的密鑰。如果缺省,會從指定的源或目標版本包的META/misc_info.txt文件中獲取,或使用"build/target/product/security/testkey"。對於制作增量升級包,默認的密鑰是基於源版本包文件META/misc_info.txt中的指定的路徑下的密鑰對,而不是從目標版本包裏的文件中獲取,這點應該註意到。
-i (--incremental_from) <file>
-i參數後指定的zip將作為差分包制作的源版本包處理
-w (--wipe_user_data)
生成在安裝時擦除user date分區的升級包
-n (--no_prereq)
忽略時間戳檢查,用於開發過程中的OTA包的經常升降級
-e (--extra_script) <file>
在制作的升級包中的升級腳本中插入外部的腳本。
-a (--aslr_mode) <on|off>
指定是否打開升級包的aslr模式,默認為on狀態
-p (--path) <dir>
指定一個路徑,作為工具在運行過程中搜索二進制可執行文件的路徑。在升級包制作中,我們一般指定/out/host/linux-x86目錄,作為搜索簽名工具的路徑。
-f (--fota) <fota>
指定是否使用 fota升級方式,默認為不使用。
4、制作增量或完整升級包

制作升級包時,需要在產品代碼編譯環境上進行。需要指定簽名工具和密鑰文件所在路徑。其中,簽名工具所在路徑用參數-p指定,這個路徑是/out/host/linux-x86。密鑰文件所在路徑可以不指定,這樣會采用默認值,由工具自動從新舊升級包中的文件解析出來。
4.1 制作增量升級包
$Source_root/build/tools/releasetools/ota_from_target_files –p $soure_root/out/host/linux-x86 –i $old_OTA_zip $new_OTA_zip $Out_diff.zip
其中,-p $soure_root/out/host/linux-x86指定一個path,是工具處理過程中對簽名工具的搜索範圍目錄
-I $old_OTA_zip $new_OTA_zip指定從$old_OTA_zip文件到$new_OTA_zip的增量升級包制作
最後的$Out_diff.zip指定輸出的增量升級包文件路徑和名稱。
4.2 制作完整升級包

$Source_root/build/tools/releasetools/ota_from_target_files –p $soure_root/out/host/linux-x86 $new_OTA_zip $Out_full.zip
其中,只需要指定簽名工具的搜索範圍、新的版本包zip文件和輸出的完整升級包的文件路徑和名稱。
5、工具處理過程
用文本編輯器或ecliipe等集成開發環境打開工具入口ota_from_target_files文件,可以看到,工具導入了和其在同一目錄的其它兩個模塊common.py和edify_generator.py。其中,common.py中包含一些工具的通用處理過程,edify_generator.py放置recovery模式的腳本生成處理過程。
轉跳到文件的末尾,if __name__ == ‘__main__’是代碼入口,如下:

5.1 平臺差異處理

首先調用Common.py模塊中的common.CloseInheritedPipes()進行平臺差異處理。由於在Mac OS上有file descriptor (PIPE) 泄露情況,所以先進行預處理。此過程對Windows或Linux平臺不做處理,處理過程如下:
if platform.system() != "Darwin":
return
5.2 入參傳遞
main(sys.argv[1:])
在運行平臺差異化處理後,調用main(sys.argv[1:])進入制作OAT包的處理過程。其中,main(sys.argv[1:])接受從命令行傳入的所有參數。
5.3 參數解析處理
option_handler()、common.ParseOptions()
對命令行傳入的參數分析處理,存儲到OPTIONS.的全局變量中。如果參數個數不為2,將直接輸出工具的文檔字串,然後退出,如下:

5.4 載入外部腳本(參數-e處理)
如果有入參指定了外部腳本,則首先打開外部腳本待用。外部腳本文件將附加到增量升級包或完整升級包的安裝腳本末尾。如下:

5.5 源或目標版本zip包解析
不管是進入增量升級包處理流程,還是完整升級包處理流程,都是先對目標版本包 (new_zip)進行解析,這是符合合理處理過程的流程。如果用戶指定了-i參數,再對源版本包(old_zip)進行解析。
版本包解析後,會將結果存到變量OPTIONS. info_dict或OPTIONS. source_info_dictk中。這個數據結構體中存儲的數據參考如下:

附 解析的OPTIONS. info_dict參考:

5.6 WriteFullOTAPackage()完整升級包處理過程
5.6.1 完整升級包處理假定
完整升級包的生成處理,存在一個問題:不確定上一版本的recovery_api_version,有可能很早。所以就假定recovery_api_version不會經常變動,否則將會影響正常升級。這一點在增量升級機制中是不存在的。
5.6.2 增量升級包中文件生成原則
包中其它文件生成過程是一個復制文件的和打包的過程:將system/下文件復制過輸出zip包,獲取boot.img,recovery.img打包的過程。
5.6.3 其它處理過程
包括生成完整升級包的安裝腳本,文件大小超限判斷等。升級腳本位於完整升級包zip文件\META-INF\com\google\androi\updater-script。
根據版本zip解析出的OPTIONS. info_dict裏fstab/yaffs2,判斷boot.img大小是否超限。
5.7 WriteIncrementalOTAPackage()增量升級包處理過程
5.7.1增量升級包處理

解壓source 版本包,解析zip包中文件,將結果在存儲到變量,此過程請參考5.5節。
5.7.2 相關參數處理
OPTIONS.package_key:獲得密鑰文件路徑,如果用戶不指定-k參數,將默認從source_zip包中的文件裏提取。
OPTIONS.verbose:處理過程可見到STD_OUT。
5.7.3 增量升級包處理封裝
WriteIncrementalOTAPackage(input_zip, source_zip, output_zip, OPTIONS.fota)
其中,Input_zip、source_zip、out_zip分別傳入target_zip,source_zip和輸出zip包對像的ID/地址,OPTIONS.fota指定fota模式的ture或false。
1、判斷從源版本zip包中獲得到的recovery_api_version值,如果為0,給出warning指示:

2、裝載源和目標版本zip包中的system/目錄下文件到內存文件對像待處理。


3、比較源和目標版本中的文件,分類處理,代碼如下:

verbatim_targets = [] #存儲不需要處理或必須原封不動地包含和保留的文件列表,這些需要保護的或不需要保護的文件在代碼中可以指定,如下:

如果在此過程中,碰到需要保護的文件,就原封不動地添加到輸出zip文件中。
diffs = [] #存儲差異文件的列表,通過比較file.sha1值。如果sha1值不同,就附加到差異文件列表中,待後續處理。如果sha1值相同,則認為源版本zip中的此文件和目標版本zip中的相應文件是完全相同的。
4、計算上述差異列表中的文件之間的差異,生成並最終的差異文件(patch),這些文件都是以.p後綴名結尾的文件。這個封裝裏還會統計出生成patch的時候,patch文件與原文件的百分比大小,並將這些信息輸出到STD_OUT上供用戶參考。
差異文件處理入口:

差分文件生成封裝:

輸出到STD_OUT效果:

5、差異文件添加到增量升級包規則,如下:

如果差異文件不存在(None)即新增,或差異文件的與原文件相差不大(一定比例%95的閾值為判斷標準),那這個文件將不做處理,也直接添加到將到生成的增量升級包中。
6、進入後續的其它處理,主要是增量升級腳本生成。最終生成的升級腳本可參考增量升級zip包\META-INF\com\google\android\updater-script。
5.8 關閉輸出zip包和簽名輸出
關閉打開狀態的輸出增量升級包或完整升級,然後對其簽名,輸出到args[1]定義的目錄位置。簽名key位置由全局變量OPTIONS.package_key定義。處理過程下:


5.9 清理環境
清理在處理過程中用到的,生成的臨時目錄。
5.10 Done
OTA分析之updater
升級包裏的updater-binary
1、OTA升級包中的updater-binary
2、Android_4.4/build/tools/releasetools/edify_generator.py中第283行

3、update-binary作為update-script的解析器,升級執行的實現
Recovery接受升級包簡要流程:
1、進入到OTA ——手動通過recovery UI指定OTA升級包
——通過/cache/recovery/command入口文件指定OTA包
2、Recovery接受外部參數:recovery --update-zip =/cache/update.zip –locale=lz_CN
3、Recovery進程進入升級包安裝處理
4、Recovery進程從1022行開始處理update包

5、Recovery中安裝邏輯開始之後的跳轉
Recovery.cpp 1023:
status = install_package(update_package, &wipe_cache, TEMPORARY_INSTALL_FILE);
install.cpp 244:
result = really_install_package(path, wipe_cache);
install.cpp 226
return try_update_binary(path, &zip, wipe_cache);
install.cpp 48 真正執行update-binary解析update-script文件的時候
// If the package contains an update binary, extract it and run it.
static int
try_update_binary(const char *path, ZipArchive *zip, int* wipe_cache) {

OTA升級包制作工具處理過程分析