您的位置:首页 > 移动开发 > Android开发

Android OTA 升级之一:编译升级包

2013-11-11 18:18 260 查看
作者:宋立新
Email:zjujoe@yahoo.com

前言

OTA升级是Android系统提供的标准软件升级方式。它功能强大,提供了完全升级、增量升级模式,可以通过SD卡升级,也可以通过网络升级。

这里,我们先研究最简单的情况,通过SD卡进行完全升级。

如何执行升级就不多说了,网上有很多资料。(比如,介绍HTC手机如何升级)。我们感兴趣的是它是如何实现的,作为开发者,如何修改它以符合我们的定制化需求。

首先,我们研究一下ota升级包的编译过程。

Quickstart

首先编译出android,然后执行:

makeotapackage

即可获得:out/target/product/{product_name}/{product_name}-ota-eng.{uid}.zip

将该文件改名为update.zip放到T卡根目录,即可开始recovery模式下的OTA升级。

编译过程研究

主要分两步,第一步,会准备一个包,其中包含升级需要的内容(原材料),比如,system目录。

第二步,运行python脚本./build/tools/releasetools/ota_from_target_files,以步骤一准备的ZIP包作为输入,最终生成需要的升级包。

步骤一

编译脚本如下:

(From:build/core/Makefile)

[c-sharp]
viewplaincopyprint?

1073#Dependingonthevariousimagesguaranteesthattheunderlying
1074#directoriesareup-to-date.
1075$(BUILT_TARGET_FILES_PACKAGE):/
1076$(INSTALLED_BOOTIMAGE_TARGET)/
1077$(INSTALLED_RADIOIMAGE_TARGET)/
1078$(INSTALLED_RECOVERYIMAGE_TARGET)/
1079$(INSTALLED_FACTORYIMAGE_TARGET)/
1080$(INSTALLED_SYSTEMIMAGE)/
1081$(INSTALLED_USERDATAIMAGE_TARGET)/
1082$(INSTALLED_SECROIMAGE_TARGET)/
1083$(INSTALLED_ANDROID_INFO_TXT_TARGET)/
1084$(built_ota_tools)/
1085$(APKCERTS_FILE)/
1086$(HOST_OUT_EXECUTABLES)/fs_config/
1087|$(ACP)
1088@echo"Packagetargetfiles:$@"
1089$(hide)rm-rf$@$(zip_root)
1090$(hide)mkdir-p$(dir$@)$(zip_root)
1091@#Componentsoftherecoveryimage
1092$(hide)mkdir-p$(zip_root)/RECOVERY
1093$(hide)$(callpackage_files-copy-root,/
1094$(TARGET_RECOVERY_ROOT_OUT),$(zip_root)/RECOVERY/RAMDISK)
1095ifdefINSTALLED_KERNEL_TARGET
1096$(hide)$(ACP)$(INSTALLED_KERNEL_TARGET)$(zip_root)/RECOVERY/kernel
1097$(hide)$(ACP)$(recovery_ramdisk)$(zip_root)/RECOVERY/ramdisk
1098endif
1099ifdefINSTALLED_2NDBOOTLOADER_TARGET
1100$(hide)$(ACP)/
1101$(INSTALLED_2NDBOOTLOADER_TARGET)$(zip_root)/RECOVERY/second
1102endif
1103ifdefBOARD_KERNEL_CMDLINE
1104$(hide)echo"$(BOARD_KERNEL_CMDLINE)">$(zip_root)/RECOVERY/cmdline
1105endif
1106ifdefBOARD_KERNEL_BASE
1107$(hide)echo"$(BOARD_KERNEL_BASE)">$(zip_root)/RECOVERY/base
1108endif
1109@#Componentsofthefactoryimage
1110$(hide)mkdir-p$(zip_root)/FACTORY
1111$(hide)$(callpackage_files-copy-root,/
1112$(TARGET_FACTORY_ROOT_OUT),$(zip_root)/FACTORY/RAMDISK)
1113ifdefINSTALLED_KERNEL_TARGET
1114$(hide)$(ACP)$(INSTALLED_KERNEL_TARGET)$(zip_root)/FACTORY/kernel
1115endif
1116ifdefINSTALLED_2NDBOOTLOADER_TARGET
1117$(hide)$(ACP)/
1118$(INSTALLED_2NDBOOTLOADER_TARGET)$(zip_root)/FACTORY/second
1119endif
1120ifdefBOARD_KERNEL_CMDLINE
1121$(hide)echo"$(BOARD_KERNEL_CMDLINE)">$(zip_root)/FACTORY/cmdline
1122endif
1123ifdefBOARD_KERNEL_BASE
1124$(hide)echo"$(BOARD_KERNEL_BASE)">$(zip_root)/FACTORY/base
1125endif
1126@#Componentsofthebootimage
1127$(hide)mkdir-p$(zip_root)/BOOT
1128$(hide)$(callpackage_files-copy-root,/
1129$(TARGET_ROOT_OUT),$(zip_root)/BOOT/RAMDISK)
1130ifdefINSTALLED_KERNEL_TARGET
1131$(hide)$(ACP)$(INSTALLED_KERNEL_TARGET)$(zip_root)/BOOT/kernel
1132$(hide)$(ACP)$(INSTALLED_RAMDISK_TARGET)$(zip_root)/BOOT/ramdisk
1133endif
1134ifdefINSTALLED_2NDBOOTLOADER_TARGET
1135$(hide)$(ACP)/
1136$(INSTALLED_2NDBOOTLOADER_TARGET)$(zip_root)/BOOT/second
1137endif
1138ifdefBOARD_KERNEL_CMDLINE
1139$(hide)echo"$(BOARD_KERNEL_CMDLINE)">$(zip_root)/BOOT/cmdline
1140endif
1141ifdefBOARD_KERNEL_BASE
1142$(hide)echo"$(BOARD_KERNEL_BASE)">$(zip_root)/BOOT/base
1143endif
1144$(hide)$(foreacht,$(INSTALLED_RADIOIMAGE_TARGET),/
1145mkdir-p$(zip_root)/RADIO;/
1146$(ACP)$(t)$(zip_root)/RADIO/$(notdir$(t));)
1147@#Contentsofthesystemimage
1148$(hide)$(callpackage_files-copy-root,/
1149$(SYSTEMIMAGE_SOURCE_DIR),$(zip_root)/SYSTEM)
1150@#Contentsofthedataimage
1151$(hide)$(callpackage_files-copy-root,/
1152$(TARGET_OUT_DATA),$(zip_root)/DATA)
1153@#ExtracontentsoftheOTApackage
1154$(hide)mkdir-p$(zip_root)/OTA/bin
1155$(hide)$(ACP)$(INSTALLED_ANDROID_INFO_TXT_TARGET)$(zip_root)/OTA/
1156$(hide)$(ACP)$(PRIVATE_OTA_TOOLS)$(zip_root)/OTA/bin/
1157@#Filesthatdonotendupinanyimages,butarenecessaryto
1158@#buildthem.
1159$(hide)mkdir-p$(zip_root)/META
1160$(hide)$(ACP)$(APKCERTS_FILE)$(zip_root)/META/apkcerts.txt
1161$(hide)echo"$(PRODUCT_OTA_PUBLIC_KEYS)">$(zip_root)/META/otakeys.txt
1162$(hide)echo"$(PRIVATE_RECOVERY_API_VERSION)">$(zip_root)/META/recovery-api-version.txt
1163$(hide)echo"blocksize$(BOARD_FLASH_BLOCK_SIZE)">$(zip_root)/META/imagesizes.txt
1164$(hide)echo"boot$(callimage-size-from-data-size,$(BOARD_BOOTIMAGE_PARTITION_SIZE))">>$(zip_root)/META/imagesizes.txt
1165$(hide)echo"recovery$(callimage-size-from-data-size,$(BOARD_RECOVERYIMAGE_PARTITION_SIZE))">>$(zip_root)/META/imagesizes.txt
1166$(hide)echo"system$(callimage-size-from-data-size,$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))">>$(zip_root)/META/imagesizes.txt
1167$(hide)echo"secro$(callimage-size-from-data-size,$(BOARD_SECROIMAGE_PARTITION_SIZE))">>$(zip_root)/META/imagesizes.txt
1168$(hide)echo"userdata$(callimage-size-from-data-size,$(BOARD_USERDATAIMAGE_PARTITION_SIZE))">>$(zip_root)/META/imagesizes.txt
1169$(hide)echo"$(tool_extensions)">$(zip_root)/META/tool-extensions.txt
1170@#Zipeverythingup,preservingsymlinks
1171$(hide)(cd$(zip_root)&&zip-qry../$(notdir$@).)
1172@#Runfs_configonallthesystemfilesinthezip,andsavetheoutput
1173$(hide)zipinfo-1$@|awk-F/'BEGIN{OFS="/"}/^SYSTEM///{$$1="system";print}'|$(HOST_OUT_EXECUTABLES)/fs_config>$(zip_root)/META/filesystem_config.txt
1174$(hide)(cd$(zip_root)&&zip-q../$(notdir$@)META/filesystem_config.txt)

1073#Dependingonthevariousimagesguaranteesthattheunderlying1074#directoriesareup-to-date.1075$(BUILT_TARGET_FILES_PACKAGE):/1076$(INSTALLED_BOOTIMAGE_TARGET)/1077$(INSTALLED_RADIOIMAGE_TARGET)/1078$(INSTALLED_RECOVERYIMAGE_TARGET)/1079$(INSTALLED_FACTORYIMAGE_TARGET)/1080$(INSTALLED_SYSTEMIMAGE)/1081$(INSTALLED_USERDATAIMAGE_TARGET)/1082$(INSTALLED_SECROIMAGE_TARGET)/1083$(INSTALLED_ANDROID_INFO_TXT_TARGET)/1084$(built_ota_tools)/1085$(APKCERTS_FILE)/1086$(HOST_OUT_EXECUTABLES)/fs_config/1087|$(ACP)1088@echo"Packagetargetfiles:$@"1089$(hide)rm-rf$@$(zip_root)1090$(hide)mkdir-p$(dir$@)$(zip_root)1091@#Componentsoftherecoveryimage1092$(hide)mkdir-p$(zip_root)/RECOVERY1093$(hide)$(callpackage_files-copy-root,/1094$(TARGET_RECOVERY_ROOT_OUT),$(zip_root)/RECOVERY/RAMDISK)1095ifdefINSTALLED_KERNEL_TARGET1096$(hide)$(ACP)$(INSTALLED_KERNEL_TARGET)$(zip_root)/RECOVERY/kernel1097$(hide)$(ACP)$(recovery_ramdisk)$(zip_root)/RECOVERY/ramdisk1098endif1099ifdefINSTALLED_2NDBOOTLOADER_TARGET1100$(hide)$(ACP)/1101$(INSTALLED_2NDBOOTLOADER_TARGET)$(zip_root)/RECOVERY/second1102endif1103ifdefBOARD_KERNEL_CMDLINE1104$(hide)echo"$(BOARD_KERNEL_CMDLINE)">$(zip_root)/RECOVERY/cmdline1105endif1106ifdefBOARD_KERNEL_BASE1107$(hide)echo"$(BOARD_KERNEL_BASE)">$(zip_root)/RECOVERY/base1108endif1109@#Componentsofthefactoryimage1110$(hide)mkdir-p$(zip_root)/FACTORY1111$(hide)$(callpackage_files-copy-root,/1112$(TARGET_FACTORY_ROOT_OUT),$(zip_root)/FACTORY/RAMDISK)1113ifdefINSTALLED_KERNEL_TARGET1114$(hide)$(ACP)$(INSTALLED_KERNEL_TARGET)$(zip_root)/FACTORY/kernel1115endif1116ifdefINSTALLED_2NDBOOTLOADER_TARGET1117$(hide)$(ACP)/1118$(INSTALLED_2NDBOOTLOADER_TARGET)$(zip_root)/FACTORY/second1119endif1120ifdefBOARD_KERNEL_CMDLINE1121$(hide)echo"$(BOARD_KERNEL_CMDLINE)">$(zip_root)/FACTORY/cmdline1122endif1123ifdefBOARD_KERNEL_BASE1124$(hide)echo"$(BOARD_KERNEL_BASE)">$(zip_root)/FACTORY/base1125endif1126@#Componentsofthebootimage1127$(hide)mkdir-p$(zip_root)/BOOT1128$(hide)$(callpackage_files-copy-root,/1129$(TARGET_ROOT_OUT),$(zip_root)/BOOT/RAMDISK)1130ifdefINSTALLED_KERNEL_TARGET1131$(hide)$(ACP)$(INSTALLED_KERNEL_TARGET)$(zip_root)/BOOT/kernel1132$(hide)$(ACP)$(INSTALLED_RAMDISK_TARGET)$(zip_root)/BOOT/ramdisk1133endif1134ifdefINSTALLED_2NDBOOTLOADER_TARGET1135$(hide)$(ACP)/1136$(INSTALLED_2NDBOOTLOADER_TARGET)$(zip_root)/BOOT/second1137endif1138ifdefBOARD_KERNEL_CMDLINE1139$(hide)echo"$(BOARD_KERNEL_CMDLINE)">$(zip_root)/BOOT/cmdline1140endif1141ifdefBOARD_KERNEL_BASE1142$(hide)echo"$(BOARD_KERNEL_BASE)">$(zip_root)/BOOT/base1143endif1144$(hide)$(foreacht,$(INSTALLED_RADIOIMAGE_TARGET),/1145mkdir-p$(zip_root)/RADIO;/1146$(ACP)$(t)$(zip_root)/RADIO/$(notdir$(t));)1147@#Contentsofthesystemimage1148$(hide)$(callpackage_files-copy-root,/1149$(SYSTEMIMAGE_SOURCE_DIR),$(zip_root)/SYSTEM)1150@#Contentsofthedataimage1151$(hide)$(callpackage_files-copy-root,/1152$(TARGET_OUT_DATA),$(zip_root)/DATA)1153@#ExtracontentsoftheOTApackage1154$(hide)mkdir-p$(zip_root)/OTA/bin1155$(hide)$(ACP)$(INSTALLED_ANDROID_INFO_TXT_TARGET)$(zip_root)/OTA/1156$(hide)$(ACP)$(PRIVATE_OTA_TOOLS)$(zip_root)/OTA/bin/1157@#Filesthatdonotendupinanyimages,butarenecessaryto1158@#buildthem.1159$(hide)mkdir-p$(zip_root)/META1160$(hide)$(ACP)$(APKCERTS_FILE)$(zip_root)/META/apkcerts.txt1161$(hide)echo"$(PRODUCT_OTA_PUBLIC_KEYS)">$(zip_root)/META/otakeys.txt1162$(hide)echo"$(PRIVATE_RECOVERY_API_VERSION)">$(zip_root)/META/recovery-api-version.txt1163$(hide)echo"blocksize$(BOARD_FLASH_BLOCK_SIZE)">$(zip_root)/META/imagesizes.txt1164$(hide)echo"boot$(callimage-size-from-data-size,$(BOARD_BOOTIMAGE_PARTITION_SIZE))">>$(zip_root)/META/imagesizes.txt1165$(hide)echo"recovery$(callimage-size-from-data-size,$(BOARD_RECOVERYIMAGE_PARTITION_SIZE))">>$(zip_root)/META/imagesizes.txt1166$(hide)echo"system$(callimage-size-from-data-size,$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))">>$(zip_root)/META/imagesizes.txt1167$(hide)echo"secro$(callimage-size-from-data-size,$(BOARD_SECROIMAGE_PARTITION_SIZE))">>$(zip_root)/META/imagesizes.txt1168$(hide)echo"userdata$(callimage-size-from-data-size,$(BOARD_USERDATAIMAGE_PARTITION_SIZE))">>$(zip_root)/META/imagesizes.txt1169$(hide)echo"$(tool_extensions)">$(zip_root)/META/tool-extensions.txt1170@#Zipeverythingup,preservingsymlinks1171$(hide)(cd$(zip_root)&&zip-qry../$(notdir$@).)1172@#Runfs_configonallthesystemfilesinthezip,andsavetheoutput1173$(hide)zipinfo-1$@|awk-F/'BEGIN{OFS="/"}/^SYSTEM///{$$1="system";print}'|$(HOST_OUT_EXECUTABLES)/fs_config>$(zip_root)/META/filesystem_config.txt1174$(hide)(cd$(zip_root)&&zip-q../$(notdir$@)META/filesystem_config.txt)

可见往里面添加了很多内容。

L1089-1090,造一个目录。

L1091-1108,填充RECOVERY子目录的内容。用于生成recovery.img。包括:kernel的image,recovery根文件系统的image,recovery根文件系统的内容:

RECOVERY$tree-L2

├──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-L2

.

├──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.

$headMETA/filesystem_config.txt

system00755

system/usr00755

system/usr/srec00755

system/usr/srec/config00755

system/usr/srec/config/en.us00755

system/usr/srec/config/en.us/grammars00755

system/usr/srec/config/en.us/grammars/phone_type_choice.g2g00644

system/usr/srec/config/en.us/grammars/VoiceDialer.g2g00644

system/usr/srec/config/en.us/grammars/boolean.g2g00644

system/usr/srec/config/en.us/g2p00755


这里,目录由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,则可以在这里加入。


步骤二

编译脚本如下:

(From:build/core/Makefile)

[c-sharp]
viewplaincopyprint?

1186name:=$(TARGET_PRODUCT)
1187ifeq($(TARGET_BUILD_TYPE),debug)
1188name:=$(name)_debug
1189endif
1190name:=$(name)-ota-$(FILE_NAME_TAG)
1191
1192INTERNAL_OTA_PACKAGE_TARGET:=$(PRODUCT_OUT)/$(name).zip
1193
1194$(INTERNAL_OTA_PACKAGE_TARGET):KEY_CERT_PAIR:=$(DEFAULT_KEY_CERT_PAIR)
1195
1196ifeq($(TARGET_OTA_SCRIPT_MODE),)
1197#defaultto"auto"
1198$(INTERNAL_OTA_PACKAGE_TARGET):scriptmode:=auto
1199else
1200$(INTERNAL_OTA_PACKAGE_TARGET):scriptmode:=$(TARGET_OTA_SCRIPT_MODE)
1201endif
1202
1203$(INTERNAL_OTA_PACKAGE_TARGET):$(BUILT_TARGET_FILES_PACKAGE)$(OTATOOLS)
1204@echo"PackageOTA:$@"
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)$@

1186name:=$(TARGET_PRODUCT)1187ifeq($(TARGET_BUILD_TYPE),debug)1188name:=$(name)_debug1189endif1190name:=$(name)-ota-$(FILE_NAME_TAG)11911192INTERNAL_OTA_PACKAGE_TARGET:=$(PRODUCT_OUT)/$(name).zip11931194$(INTERNAL_OTA_PACKAGE_TARGET):KEY_CERT_PAIR:=$(DEFAULT_KEY_CERT_PAIR)11951196ifeq($(TARGET_OTA_SCRIPT_MODE),)1197#defaultto"auto"1198$(INTERNAL_OTA_PACKAGE_TARGET):scriptmode:=auto1199else1200$(INTERNAL_OTA_PACKAGE_TARGET):scriptmode:=$(TARGET_OTA_SCRIPT_MODE)1201endif12021203$(INTERNAL_OTA_PACKAGE_TARGET):$(BUILT_TARGET_FILES_PACKAGE)$(OTATOOLS)1204@echo"PackageOTA:$@"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包。具体内容我们后文继续分析。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: