一.update.zip結(jié)構(gòu)目錄
二.對(duì)結(jié)構(gòu)目錄的解析
1.META-INF:包含升級(jí)腳本刊驴、腳本解釋器捏浊、簽名信息片择。
1)update-binary:一個(gè)二進(jìn)制文件,相當(dāng)于一個(gè)腳本解釋器曙求,能夠識(shí)別updater-script中描述的操作。
來(lái)源:/out/target/product/{project}/symbols/system/bin/updater生成夹孔,可將updater重命名為update-binary得到办陷。該文件在具體的更新包中的名字由源碼中/bootable/recovery/install.cpp中的宏ASSUMED_UPDATE_BINARY_NAME的值而定。
2)updater-script:此文件是一個(gè)腳本文件震檩,具體描述了更新過程琢蛤。我們可以根據(jù)具體情況編寫該腳本來(lái)適應(yīng)我們的具體需求。
來(lái)源:編譯過程由build/tools/releasetools/ota_from_target_files抛虏、ota_from_target_files.pt博其、edify_generator.py共同合力產(chǎn)生,其中涉及的內(nèi)容定義可跟bootable/recovery/updater/install.cpp的RegisterInstallFunctions方法查看迂猴。該文件的命名由源碼中bootable/recovery/updater/updater.cpp文件中的宏SCRIPT_NAME的值而定慕淡。
3)metadata:描述設(shè)備信息及環(huán)境變量的元數(shù)據(jù)。主要包括一些編譯選項(xiàng)沸毁,簽名公鑰峰髓,時(shí)間戳以及設(shè)備型號(hào)等。
4)MANIFEST.MF:這個(gè)manifest文件定義了與包的組成結(jié)構(gòu)相關(guān)的數(shù)據(jù)息尺。類似Android應(yīng)用的mainfest.xml文件携兵。
5)CERT.RSA:與簽名文件相關(guān)聯(lián)的簽名程序塊文件,它存儲(chǔ)了用于簽名JAR文件的公共簽名搂誉。簽名采用非對(duì)稱簽名RSA
6)CERT.SF:這是JAR文件的簽名文件徐紧,其中前綴CERT代表簽名者。
備注:
在具體升級(jí)時(shí)炭懊,對(duì)update.zip包檢查時(shí)大致會(huì)分三步:
①檢驗(yàn)SF文件與RSA文件是否匹配并级。
②檢驗(yàn)MANIFEST.MF與簽名文件中的digest是否一致。
③檢驗(yàn)包中的文件與MANIFEST中所描述的是否一致
2.system包
1)system.new.dat:它實(shí)際上是由system.transfer.list描述的一個(gè)稀疏數(shù)組侮腹,這個(gè)過程的主要目的是降低ota.zip的大小嘲碧,將system.img轉(zhuǎn)換成為稀疏數(shù)組描述。
2)system.patch.dat:升級(jí)包中用于patch的數(shù)據(jù)
3)system.transfer.list:升級(jí)命令執(zhí)行列表父阻,由build/tools/releasetools/blockimgdiff.py生成
三.update包的簽名
1.簽名腳本:
java -Xmx2048m -jar signapk.jar -w testkey.x509.pem testkey.pk8 update_tmp.zip update_signed.zip
注:
可能有些update.zip的簽名方式不一樣愈涩。
更準(zhǔn)確的方法是查看log:
/out/target/product/{project}_otapackage.log中的最后幾行標(biāo)注的,其中加矛,它也詳細(xì)的標(biāo)注了所用的簽名文件所在的目錄
2.一般簽名:key
testkey.x509.pem
獲取路徑:build/target/product/security/testkey.x509.pem
testkey.pk8
獲取路徑:build/target/product/security/testkey.pk8
注: pem/pk8的準(zhǔn)確來(lái)源钠署,可從源包(做差分包的包)的MATA/mic_info.txt中查看 default_system_dev_certificate=build/target/product/security/testkey
signapk.jar
獲取路徑:out/host/linux-x86/framework/signapk.jar
-Xmx2048m
獲取路徑:
build\tools\releasetools下的common.py:
self.java_args -- 對(duì)應(yīng)Xmx2048m的來(lái)源
self.signapk_path -- 對(duì)應(yīng)signapk.jar的來(lái)源
3.案例
#!/bin/bash
cd update
zip -r ../update_unsign.zip ./*
cd ../
echo "zipping finished"
java -Xmx2048m -jar signapk.jar -w testkey.x509.pem testkey.pk8 update_unsign.zip update_sign.zip
sudo rm update_unsign.zip
四.update腳本updater-script詳解
對(duì)應(yīng)的實(shí)現(xiàn)路徑為:bootable\recovery\updater\install.cpp
void RegisterInstallFunctions() {
RegisterFunction("mount", MountFn);
RegisterFunction("is_mounted", IsMountedFn);
RegisterFunction("unmount", UnmountFn);
RegisterFunction("format", FormatFn);
RegisterFunction("show_progress", ShowProgressFn);
RegisterFunction("set_progress", SetProgressFn);
RegisterFunction("delete", DeleteFn);
RegisterFunction("delete_recursive", DeleteFn);
RegisterFunction("package_extract_dir", PackageExtractDirFn);
RegisterFunction("package_extract_file", PackageExtractFileFn);
RegisterFunction("symlink", SymlinkFn);
···
RegisterFunction("getprop", GetPropFn);
RegisterFunction("file_getprop", FileGetPropFn);
RegisterFunction("write_raw_image", WriteRawImageFn);
···
RegisterFunction("apply_patch", ApplyPatchFn);
RegisterFunction("wipe_cache", WipeCacheFn);
RegisterFunction("ui_print", UIPrintFn);
···
RegisterFunction("enable_reboot", EnableRebootFn);
RegisterFunction("tune2fs", Tune2FsFn);
}
五.系統(tǒng)編譯的全量包和差分包來(lái)源
1.全量包
build/core/Makefile
ifeq ($(build_ota_package),true)
# -----------------------------------------------------------------
# OTA update package
name := $(TARGET_PRODUCT)
ifeq ($(TARGET_BUILD_TYPE),debug)
name := $(name)_debug
endif
name := $(name)-ota-$(FILE_NAME_TAG)
INTERNAL_OTA_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip
$(INTERNAL_OTA_PACKAGE_TARGET): KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR)
$(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(HOST_OUT_EXECUTABLES)/mkparameter $(HOST_OUT_EXECUTABLES)/drmsigntool
@echo "Package OTA: $@"
$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \
./build/tools/releasetools/ota_from_target_files -v \
--block \ ## 這里使用ota_from_target_files的參數(shù)為-v和--block
-p $(HOST_OUT) \
-k $(KEY_CERT_PAIR) \
$(if $(OEM_OTA_CONFIG), -o $(OEM_OTA_CONFIG)) \
$(BUILT_TARGET_FILES_PACKAGE) $@
.PHONY: otapackage
otapackage: $(INTERNAL_OTA_PACKAGE_TARGET)
endif # build_ota_package
2.差分包
#!/bin/bash
color_red='\E[1;31m'
color_end='\E[0m'
root_path=`pwd`
ota_name="buildTools/OTA"
ota_path=$root_path/$ota_name
old_path=$ota_path/old.zip
new_path=$ota_path/new.zip
update_path=$ota_path/update.zip
echo ---------------------------begin update.zip---------------------------
echo $old_path
if [ ! -e $old_path ]; then
echo -e "$color_red--$old_path is not exist--$color_end"
exit 0
fi
echo $new_path
if [ ! -e $new_path ]; then
echo "$color_red--$new_path is not exist--$color_end"
exit 0
fi
echo $update_path
if [ -e $update_path ]; then
echo "delete $update_path"
rm -fr $update_path
fi
./build/tools/releasetools/ota_from_target_files -v -i $old_path $new_path $update_path
echo -----------------------------end update.zip------------------------------
## 關(guān)鍵點(diǎn):ota_from_target_files -v -i #-i就是差分包 -v是校驗(yàn)verify
3.框架圖
參考學(xué)習(xí)
https://blog.csdn.net/chi_wy/article/details/82777895 https://chendongqi.me/2019/01/04/updater/ https://blog.csdn.net/luzhenrong45/article/details/60968458?utm_source=blogxgwz9 https://blog.csdn.net/wanshilun/article/details/77337734 https://blog.csdn.net/huangyabin001/article/details/44838315 https://source.android.google.cn/devices/tech/ota/nonab/inside_packages?hl=zh-cn