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

转载地址:http://blog.csdn.net/zjujoe/article/details/6206010

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

作者: 宋立新

Email:zjujoe@yahoo.com

前言

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

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

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

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

Quick start

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

make otapackage

    即可获得: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)

    1073 # Depending on the various images guarantees that the underlying  
    1074 # directories are up-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 "Package target files: $@"  
    1089         $(hide) rm -rf $@ $(zip_root)  
    1090         $(hide) mkdir -p $(dir $@) $(zip_root)  
    1091         @# Components of the recovery image  
    1092         $(hide) mkdir -p $(zip_root)/RECOVERY  
    1093         $(hide) $(call package_files-copy-root, /  
    1094                 $(TARGET_RECOVERY_ROOT_OUT),$(zip_root)/RECOVERY/RAMDISK)  
    1095 ifdef INSTALLED_KERNEL_TARGET  
    1096         $(hide) $(ACP) $(INSTALLED_KERNEL_TARGET) $(zip_root)/RECOVERY/kernel  
    1097         $(hide) $(ACP) $(recovery_ramdisk) $(zip_root)/RECOVERY/ramdisk  
    1098 endif  
    1099 ifdef INSTALLED_2NDBOOTLOADER_TARGET  
    1100         $(hide) $(ACP) /  
    1101                 $(INSTALLED_2NDBOOTLOADER_TARGET) $(zip_root)/RECOVERY/second  
    1102 endif  
    1103 ifdef BOARD_KERNEL_CMDLINE  
    1104         $(hide) echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/RECOVERY/cmdline  
    1105 endif  
    1106 ifdef BOARD_KERNEL_BASE  
    1107         $(hide) echo "$(BOARD_KERNEL_BASE)" > $(zip_root)/RECOVERY/base  
    1108 endif  
    1109         @# Components of the factory image  
    1110         $(hide) mkdir -p $(zip_root)/FACTORY  
    1111         $(hide) $(call package_files-copy-root, /  
    1112                 $(TARGET_FACTORY_ROOT_OUT),$(zip_root)/FACTORY/RAMDISK)  
    1113 ifdef INSTALLED_KERNEL_TARGET  
    1114         $(hide) $(ACP) $(INSTALLED_KERNEL_TARGET) $(zip_root)/FACTORY/kernel  
    1115 endif  
    1116 ifdef INSTALLED_2NDBOOTLOADER_TARGET  
    1117         $(hide) $(ACP) /  
    1118                 $(INSTALLED_2NDBOOTLOADER_TARGET) $(zip_root)/FACTORY/second  
    1119 endif  
    1120 ifdef BOARD_KERNEL_CMDLINE  
    1121         $(hide) echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/FACTORY/cmdline  
    1122 endif  
    1123 ifdef BOARD_KERNEL_BASE  
    1124         $(hide) echo "$(BOARD_KERNEL_BASE)" > $(zip_root)/FACTORY/base  
    1125 endif  
    1126         @# Components of the boot image  
    1127         $(hide) mkdir -p $(zip_root)/BOOT  
    1128         $(hide) $(call package_files-copy-root, /  
    1129                 $(TARGET_ROOT_OUT),$(zip_root)/BOOT/RAMDISK)  
    1130 ifdef INSTALLED_KERNEL_TARGET  
    1131         $(hide) $(ACP) $(INSTALLED_KERNEL_TARGET) $(zip_root)/BOOT/kernel  
    1132         $(hide) $(ACP) $(INSTALLED_RAMDISK_TARGET) $(zip_root)/BOOT/ramdisk  
    1133 endif  
    1134 ifdef INSTALLED_2NDBOOTLOADER_TARGET  
    1135         $(hide) $(ACP) /  
    1136                 $(INSTALLED_2NDBOOTLOADER_TARGET) $(zip_root)/BOOT/second  
    1137 endif  
    1138 ifdef BOARD_KERNEL_CMDLINE  
    1139         $(hide) echo "$(BOARD_KERNEL_CMDLINE)" > $(zip_root)/BOOT/cmdline  
    1140 endif  
    1141 ifdef BOARD_KERNEL_BASE  
    1142         $(hide) echo "$(BOARD_KERNEL_BASE)" > $(zip_root)/BOOT/base  
    1143 endif  
    1144         $(hide) $(foreach t,$(INSTALLED_RADIOIMAGE_TARGET),/  
    1145                     mkdir -p $(zip_root)/RADIO; /  
    1146                     $(ACP) $(t) $(zip_root)/RADIO/$(notdir $(t));)  
    1147         @# Contents of the system image  
    1148         $(hide) $(call package_files-copy-root, /  
    1149                 $(SYSTEMIMAGE_SOURCE_DIR),$(zip_root)/SYSTEM)  
    1150         @# Contents of the data image  
    1151         $(hide) $(call package_files-copy-root, /  
    1152                 $(TARGET_OUT_DATA),$(zip_root)/DATA)  
    1153         @# Extra contents of the OTA package  
    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         @# Files that do not end up in any images, but are necessary to  
    1158         @# build them.  
    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 $(call image-size-from-data-size,$(BOARD_BOOTIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/imagesizes.txt  
    1165         $(hide) echo "recovery $(call image-size-from-data-size,$(BOARD_RECOVERYIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/imagesizes.txt  
    1166         $(hide) echo "system $(call image-size-from-data-size,$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/imagesizes.txt  
    1167         $(hide) echo "secro $(call image-size-from-data-size,$(BOARD_SECROIMAGE_PARTITION_SIZE))" >> $(zip_root)/META/imagesizes.txt  
    1168         $(hide) echo "userdata $(call image-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         @# Zip everything up, preserving symlinks  
    1171         $(hide) (cd $(zip_root) && zip -qry ../$(notdir $@) .)  
    1172         @# Run fs_config on all the system files in the zip, and save the output  
    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)  
 

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

L1089-1090 , 造一个目录。

L1091-1108,填充 RECOVERY 子目录的内容。用于生成recovery.img。包括:kernel 的image, recovery 根文件系统的 image, recovery 根文件系统的内容:
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, 则可以在这里加入。
 

步骤二

编译脚本如下:

(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) $@  
核心是一个python脚本: ota_from_target_files, 它以前一步骤生成的ZIP包作为输入,生成可用于OTA升级的zip包。 具体内容我们后文继续分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值