1. OTA功能介绍
OTA 升级是 Android 系统提供的标准软件升级方式。 它功能强大,提供了全量升级和增量升级模式,可以通过SD卡或U盘升级,也可以通过网络升级。这里,我们先研究最简单的情况,通过SD卡进行完全升级。
2. 编译OTA全量升级包
1) 首先编译出android
2) make otapackage
即可获得:out/target/product/{product_name}/ {product_name}-ota-eng.{uid}.zip
3) 将该文件改名为update.zip放到SD卡根目录, 即可开始recovery模式下的OTA升级。
3. 编译过程研究
主要分两步:
第一步,准备一个包,其中包含升级需要的内容(原材料),比如,system 目录。
第二步,运行python 脚本 ./build/tools/releasetools/ota_from_target_files,以第一步准备的ZIP包作为输入,最终生成需要的升级包。
1) 步骤一
编译脚本如下:
(From: build/core/Makefile)
RECOVERY$ tree -L 2
├── kernel
├── ramdisk
└── RAMDISK
├── advanced_meta_init.rc
├── data
├── default.prop
├── dev
├── etc
├── init
├── init.factory.rc
├── init.goldfish.rc
├── init.mt6516.rc
├── init.rc
├── meta_init.rc
├── proc
├── res
├── sbin
├── sys
├── system
└── tmp
L1109-1125, 填充 FACTORY 子目录的内容, 没有用到,包括:kernel 的image
L1126-1143, 填充 BOOT子目录的内容,用于生成boot.img。和 RECOVERY目录类似,包括:kernel 的image,根文件系统的 image,根文件系统的内容:
BOOT$ tree -L 2
.
├── kernel
├── ramdisk
└── RAMDISK
├── advanced_meta_init.rc
├── data
├── default.prop
├── dev
├── init
├── init.factory.rc
├── init.goldfish.rc
├── init.mt6516.rc
├── init.rc
├── meta_init.rc
├── proc
├── res -> /system/res
├── sbin
├── sys
└── system
L1144-1146, 填充 RADIO子目录的内容, 没有用到。
L1147-1149, 填充 SYSTEM子目录的内容。 这是升级的主要内容。
L1150-1152, 填充 DATA子目录的内容。缺省没有用到。
L1153-1156, 填充 OTA/bin子目录的内容,这是OTA升级自己使用的程序。后面会遇到。
OTA/bin$ tree
.
├── applypatch
├── applypatch_static
├── check_prereq
└── updater
L1159-1169, 填充 META子目录的内容,这里包含了OTA脚本需要的一些附加信息。
L1170-1171,将所有内容打包。供下一阶段使用。
L1173-1174,生成 META/filesystem_config.txt 并将其加入到 zip 包中。该文件保存了 system 目录下各目录、文件的权限及 owner.
$ head META/filesystem_config.txt
system 0 0 755
system/usr 0 0 755
system/usr/srec 0 0 755
system/usr/srec/config 0 0 755
system/usr/srec/config/en.us 0 0 755
system/usr/srec/config/en.us/grammars 0 0 755
system/usr/srec/config/en.us/grammars/phone_type_choice.g2g 0 0 644
system/usr/srec/config/en.us/grammars/VoiceDialer.g2g 0 0 644
system/usr/srec/config/en.us/grammars/boolean.g2g 0 0 644
system/usr/srec/config/en.us/g2p 0 0 755
这里,目录由 zipinfo –l 提供, 而权限则由 fs_config 设定。此程序的源码位于:build/tools/fs_config, 其中fs_config 包含了一个头文件:
54 #include "private/android_filesystem_config.h"
这个文件(system/core/include/private/android_filesystem_config.h)以hardcoding 的方式设定了 system 下各目录、文件的权限、属主。比如:
152 { 00440, AID_ROOT, AID_SHELL, "system/etc/init.goldfish.rc" },
153 { 00550, AID_ROOT, AID_SHELL, "system/etc/init.goldfish.sh" },
154 { 00440, AID_ROOT, AID_SHELL, "system/etc/init.trout.rc" },
155 { 00550, AID_ROOT, AID_SHELL, "system/etc/init.ril" },
如果需要升级其它内容,比如 bootloader, 则可以在这里加入。
2) 步骤二
编译脚本如下:
(From: build/core/Makefile)
- 1186 name := $(TARGET_PRODUCT)
- 1187 ifeq ($(TARGET_BUILD_TYPE),debug)
- 1188 name := $(name)_debug
- 1189 endif
- 1190 name := $(name)-ota-$(FILE_NAME_TAG)
- 1191
- 1192 INTERNAL_OTA_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip
- 1193
- 1194 $(INTERNAL_OTA_PACKAGE_TARGET): KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR)
- 1195
- 1196 ifeq ($(TARGET_OTA_SCRIPT_MODE),)
- 1197 # default to "auto"
- 1198 $(INTERNAL_OTA_PACKAGE_TARGET): scriptmode := auto
- 1199 else
- 1200 $(INTERNAL_OTA_PACKAGE_TARGET): scriptmode := $(TARGET_OTA_SCRIPT_MODE)
- 1201 endif
- 1202
- 1203 $(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(OTATOOLS)
- 1204 @echo "Package OTA: $@"
- 1205 $(hide) ./build/tools/releasetools/ota_from_target_files /
- 1206 -m $(scriptmode) /
- 1207 -p $(HOST_OUT) /
- 1208 -k $(KEY_CERT_PAIR) /
- 1209 $(BUILT_TARGET_FILES_PACKAGE) $@
1186 name := $(TARGET_PRODUCT)
1187 ifeq ($(TARGET_BUILD_TYPE),debug)
1188 name := $(name)_debug
1189 endif
1190 name := $(name)-ota-$(FILE_NAME_TAG)
1191
1192 INTERNAL_OTA_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip
1193
1194 $(INTERNAL_OTA_PACKAGE_TARGET): KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR)
1195
1196 ifeq ($(TARGET_OTA_SCRIPT_MODE),)
1197 # default to "auto"
1198 $(INTERNAL_OTA_PACKAGE_TARGET): scriptmode := auto
1199 else
1200 $(INTERNAL_OTA_PACKAGE_TARGET): scriptmode := $(TARGET_OTA_SCRIPT_MODE)
1201 endif
1202
1203 $(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(OTATOOLS)
1204 @echo "Package OTA: $@"
1205 $(hide) ./build/tools/releasetools/ota_from_target_files /
1206 -m $(scriptmode) /
1207 -p $(HOST_OUT) /
1208 -k $(KEY_CERT_PAIR) /
1209 $(BUILT_TARGET_FILES_PACKAGE) $@
核心是一个python脚本: ota_from_target_files, 它以前一步骤生成的ZIP包作为输入,生成可用于OTA升级的zip包。 具体内容我们后文继续分析。