一.update.zip结构目录
![](https://img.haomeiwen.com/i14090831/df7a27089dfbc823.png)
二.对结构目录的解析
1.META-INF:包含升级脚本、脚本解释器、签名信息。
1)update-binary:一个二进制文件,相当于一个脚本解释器,能够识别updater-script中描述的操作。
来源:/out/target/product/{project}/symbols/system/bin/updater生成,可将updater重命名为update-binary得到。该文件在具体的更新包中的名字由源码中/bootable/recovery/install.cpp中的宏ASSUMED_UPDATE_BINARY_NAME的值而定。
2)updater-script:此文件是一个脚本文件,具体描述了更新过程。我们可以根据具体情况编写该脚本来适应我们的具体需求。
来源:编译过程由build/tools/releasetools/ota_from_target_files、ota_from_target_files.pt、edify_generator.py共同合力产生,其中涉及的内容定义可跟bootable/recovery/updater/install.cpp的RegisterInstallFunctions方法查看。该文件的命名由源码中bootable/recovery/updater/updater.cpp文件中的宏SCRIPT_NAME的值而定。
3)metadata:描述设备信息及环境变量的元数据。主要包括一些编译选项,签名公钥,时间戳以及设备型号等。
4)MANIFEST.MF:这个manifest文件定义了与包的组成结构相关的数据。类似Android应用的mainfest.xml文件。
5)CERT.RSA:与签名文件相关联的签名程序块文件,它存储了用于签名JAR文件的公共签名。签名采用非对称签名RSA
6)CERT.SF:这是JAR文件的签名文件,其中前缀CERT代表签名者。
备注:
在具体升级时,对update.zip包检查时大致会分三步:
①检验SF文件与RSA文件是否匹配。
②检验MANIFEST.MF与签名文件中的digest是否一致。
③检验包中的文件与MANIFEST中所描述的是否一致
2.system包
1)system.new.dat:它实际上是由system.transfer.list描述的一个稀疏数组,这个过程的主要目的是降低ota.zip的大小,将system.img转换成为稀疏数组描述。
2)system.patch.dat:升级包中用于patch的数据
3)system.transfer.list:升级命令执行列表,由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的签名方式不一样。
更准确的方法是查看log:
/out/target/product/{project}_otapackage.log中的最后几行标注的,其中,它也详细的标注了所用的签名文件所在的目录
2.一般签名:key
testkey.x509.pem
获取路径:build/target/product/security/testkey.x509.pem
testkey.pk8
获取路径:build/target/product/security/testkey.pk8
注: pem/pk8的准确来源,可从源包(做差分包的包)的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 -- 对应Xmx2048m的来源
self.signapk_path -- 对应signapk.jar的来源
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详解
![](https://img.haomeiwen.com/i14090831/32c23baf6de53f19.png)
对应的实现路径为: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);
}
五.系统编译的全量包和差分包来源
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的参数为-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------------------------------
## 关键点:ota_from_target_files -v -i #-i就是差分包 -v是校验verify
3.框架图
![](https://img.haomeiwen.com/i14090831/4d00671fffe950a2.png)
参考学习
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
网友评论