OTA完整包生成方法
OTA完整包可用于T卡本地升级和OTA在线升级。OTA完整包包含完整的system、recovery.和boot.img。
发布一个版本固件正确顺序:
1 2 3
| make -j4 make otapackage ./mkimage.sh ota
|
即可获得:out/target/product/{product_name}/ {product_name}-ota-eng.{uid}.zip
注意:发布固件必须使用./mkimage.sh ota,将boot与kernel打包,不需要单独烧kernel,如果量产固件是分开的,将会影响后面差异包升级,除非你不需要用差异升级!
在out/target/product/rk3288/目录下会生成ota完整包rk3288-ota-eng.root.zip,改名成
update.zip即可拷贝到T卡或内置flash中进行固件升级。
OTA差异包生成方法
OTA差异包只有差异内容,包大小比较小,主要用于OTA在线升级,也可T卡本地升级。OTA差异包制作需要特殊的编译进行手动制作。
- 首先发布v1版本的固件,生成v1版本的完整包
- 保存out/target/product/rk3288/obj/PACKAGING/target_files_intermediates/rk3288-target_files-eng.root.zip 为rk3288-target_files-v1.zip,作为v1版本的基础素材包。
- 修改kernel代码或者android代码,发布v2版本固件,生成v2版本完整包
- 保存out/target/product/rk3288/obj/PACKAGING/target_files_intermediates/rk3288-target_files-eng.root.zip 为rk3288-target_files-v2.zip,作为v2版本的基础素材包。
- 生成v1-v2的差异升级包:./build/tools/releasetools/ota_from_target_files -v -i rk3288-target_files-v1.zip -p out/host/linux-x86 -k build/target/product/security/testkey rk3288-target_files-v2.zip out/target/product/rk3288/rk3288-v1-v2.zip
- 最后生成的ota差异包
编译过程
编译主要分两步,
- 会准备一个包,其中包含升级需要的内容(原材料),比如,system 目录。
- 运行python 脚本 ./build/tools/releasetools/ota_from_target_files,以步骤一准备的ZIP包作为输入,最终生成需要的升级包。
第一步:填充所需要的材料
Makefile 依赖
otapackage 是一个伪目标
1 2
| .PHONY: otapackage otapackage: $(INTERNAL_OTA_PACKAGE_TARGET)
|
RECOVERY目录下的组件
填充 RECOVERY 子目录的内容。用于生成recovery.img。包括:kernel 的image, recovery 根文件系统的 image, recovery 根文件系统的内容
1 2 3 4 5 6 7 8 9 10 11 12
| @ $(hide) mkdir -p $(zip_root)/RECOVERY //创建中间包中的RECOVERY目录 $(hide) $(call package_files-copy-root, \ $(TARGET_RECOVERY_ROOT_OUT),$(zip_root)/RECOVERY/RAMDISK) //拷贝相关分区文件到 RECOVERY 目录 1. $(ACP) $(INSTALLED_KERNEL_TARGET) $(zip_root)/RECOVERY/kernel 2. $(ACP) $(INSTALLED_2NDBOOTLOADER_TARGET) $(zip_root)/RECOVERY/second 3. echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/RECOVERY/cmdline 4. echo "$(BOARD_KERNEL_BASE)" > $(zip_root)/RECOVERY/base 5. echo "$(BOARD_KERNEL_PAGESIZE)" > $(zip_root)/RECOVERY/pagesize
|
BOOT 目录下的组件
填充 BOOT子目录的内容,用于生成boot.img。和 RECOVERY目录类似,包括:kernel 的image,根文件系统的 image,根文件系统的内容:
1 2 3 4 5 6 7 8 9 10 11
| @ $(hide) mkdir -p $(zip_root)/BOOT $(hide) $(call package_files-copy-root, \ $(TARGET_ROOT_OUT),$(zip_root)/BOOT/RAMDISK) 1. $(ACP) $(INSTALLED_KERNEL_TARGET) $(zip_root)/BOOT/kernel 2. $(ACP) $(INSTALLED_2NDBOOTLOADER_TARGET) $(zip_root)/BOOT/second 3. echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/BOOT/cmdline 4. echo "$(BOARD_KERNEL_BASE)" > $(zip_root)/BOOT/base 5. echo "$(BOARD_KERNEL_PAGESIZE)" > $(zip_root)/BOOT/pagesize 6.
|
RADIO 目录下的组件
1 2 3
| $(hide) $(foreach t,$(INSTALLED_RADIOIMAGE_TARGET),\ mkdir -p $(zip_root)/RADIO; \ $(ACP) $(t) $(zip_root)/RADIO/$(notdir $(t));)
|
BOOTLOADER 组件内容
BOOTLOADER 需要提供之前使用的 BOOTLOADER 和 新的 BOOTLOADER 文件 以及 MISC 分区文件
之前使用的BOOTLOADER 放置在目录:$(TARGET_DEVICE_DIR)/ota/loader/RKLoader.bin)
新的 BOOTLOADER 文件 放置在目录:$(PRODUCT_OUT)/RKLoader_new.bin
MISC 分区文件 放置在目录:$(TARGET_DEVICE_DIR)/ota/loader/misc_loadercmd.img
1 2 3 4 5 6 7 8
| ifeq ($(INSTALLED_LOADER_TARGET),) $(info No RK Loader for TARGET_DEVICE $(TARGET_DEVICE) to otapackage) //不需要更新BOOTLOADER else @ $(hide) mkdir -p $(zip_root)/LOADER $(hide) $(HOST_OUT_EXECUTABLES)/remkloader '$(INSTALLED_LOADER_TARGET)' $(INSTALLED_NEW_LOADER_TARGET) $(hide) cat $(INSTALLED_LOADER_MISC_TARGET) $(INSTALLED_NEW_LOADER_TARGET) > $(zip_root)/LOADER/RKLoader.img endif
|
Parameter 组件内容
parameter 需要放置在 $(TARGET_DEVICE_DIR)/ota/parameter/parameter*) 目录中
1 2 3 4 5 6 7
| ifeq ($(INSTALLED_PARAMETER_TARGET),) $(info No parameter for TARGET_DEVICE $(TARGET_DEVICE) to otapackage) //不需要更新Parameter else $(hide) rm -rf $(zip_root)/PARAMETER $(hide) mkdir -p $(zip_root)/PARAMETER $(hide) $(HOST_OUT_EXECUTABLES)/mkparameter '$(INSTALLED_PARAMETER_TARGET)' $(zip_root)/PARAMETER/parameter endif
|
常规的system 以及 data 分区内容
填充 SYSTEM子目录的内容。 这是升级的主要内容。
生成 META/filesystem_config.txt 并将其加入到 zip 包中。该文件保存了 system 目录下各目录、文件的权限及 owner
1 2 3 4 5 6
| @ $(hide) $(call package_files-copy-root, \ $(SYSTEMIMAGE_SOURCE_DIR),$(zip_root)/SYSTEM) @ $(hide) $(call package_files-copy-root, \ $(TARGET_OUT_DATA),$(zip_root)/DATA)
|
供应商定制相关内容
1 2 3 4 5
| ifdef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE @ $(hide) $(call package_files-copy-root, \ $(TARGET_OUT_VENDOR),$(zip_root)/VENDOR) endif
|
第二步:ota_from_target_files 命令执行
核心是一个python脚本: ota_from_target_files, 它以前一步骤生成的ZIP包作为输入,生成可用于OTA升级的zip包。
生成的完整升级包会存放在out\target\product[project-name]\目录下
1 2 3 4 5 6 7 8 9 10
| INTERNAL_OTA_PACKAGE_TARGET : $(INTERNAL_OTA_PACKAGE_TARGET): KEY_CERT_PAIR : $(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(DISTTOOLS) @echo "Package OTA: $@" $(hide) PATH ./build/tools/releasetools/ota_from_target_files -v \ -p $(HOST_OUT) \ -k $(KEY_CERT_PAIR) \ $(if $(OEM_OTA_CONFIG), -o $(OEM_OTA_CONFIG)) \ $(BUILT_TARGET_FILES_PACKAGE) $@
|
生成中间包
生成的中间包存放在out/target/product/[project-name]/obj/PACKAGING/target_files_intermediates/目录下,该文件可用于创建差分升级包以及全量包
源码中的英文注释为:
1 2
| A zip of the directories that map to the target filesystem. This zip can be used to create an OTA package or filesystem image as a post-build step.
|
中间包宏变量为: BUILT_TARGET_FILES_PACKAGE
部分代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| intermediates : BUILT_TARGET_FILES_PACKAGE : $(BUILT_TARGET_FILES_PACKAGE): intermediates : $(BUILT_TARGET_FILES_PACKAGE): \ zip_root : ... //省略一部分依赖说明 $(BUILT_TARGET_FILES_PACKAGE): \ $(INSTALLED_BOOTIMAGE_TARGET) \ $(INSTALLED_RADIOIMAGE_TARGET) \ $(INSTALLED_LOADER_TARGET) \ $(INSTALLED_PARAMETER_TARGET) \ $(INSTALLED_RECOVERYIMAGE_TARGET) \ $(INSTALLED_SYSTEMIMAGE) \ $(INSTALLED_USERDATAIMAGE_TARGET) \ $(INSTALLED_CACHEIMAGE_TARGET) \ $(INSTALLED_VENDORIMAGE_TARGET) \ $(INSTALLED_ANDROID_INFO_TXT_TARGET) \ $(SELINUX_FC) \ $(built_ota_tools) \ $(APKCERTS_FILE) \ $(HOST_OUT_EXECUTABLES)/fs_config \ | $(ACP) 上述依赖主要定义各个分区系统的文件 //之后执行命令 @echo "Package target files: $@" //打印日志 $(hide) rm -rf $@ $(zip_root) //删除原有文件目录 $(hide) mkdir -p $(dir $@) $(zip_root) //重新创建目录
|