骑皮皮虾是什么梗:Android OTA 升级之一:编译升级包

来源:百度文库 编辑:中财网 时间:2024/05/03 07:47:01
Android OTA 升级之一:编译升级包
分类: Android2011-02-24 19:50 7358人阅读 评论(17) 收藏 举报
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    └── tmpL1109-1125, 填充 FACTORY 子目录的内容, 没有用到,包括:kernel 的imageL1126-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└── updaterL1159-1169, 填充 META子目录的内容,这里包含了OTA脚本需要的一些附加信息。L1170-1171,将所有内容打包。供下一阶段使用。L1173-1174,生成 META/filesystem_config.txt 并将其加入到 zip 包中。该文件保存了 system 目录下各目录、文件的权限及 owner.$ head META/filesystem_config.txtsystem 0 0 755system/usr 0 0 755system/usr/srec 0 0 755system/usr/srec/config 0 0 755system/usr/srec/config/en.us 0 0 755system/usr/srec/config/en.us/grammars 0 0 755system/usr/srec/config/en.us/grammars/phone_type_choice.g2g 0 0 644system/usr/srec/config/en.us/grammars/VoiceDialer.g2g 0 0 644system/usr/srec/config/en.us/grammars/boolean.g2g 0 0 644system/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包。 具体内容我们后文继续分析。
分享到:
上一篇:关于 LOCAL_SDK_VERSION
下一篇:Android OTA 升级之二:脚本 ota_from_target_files
查看评论
11楼 luobin2601258 2011-09-24 18:09发表 [回复]

zjujoe:
你好!请教你一问题,你上面说“如果需要升级其它内容,比如 bootloader, 则可以在这里加入”。能具体说是在哪个地方加吗?或者有了例子。谢谢你的指教。
10楼 lassur 2011-09-05 15:09发表 [回复]

问一个入门问题:$(hide)这是什么意思?
Re: zjujoe 2011-09-21 21:21发表 [回复]

回复lassur:不显示这条命令的输出信息。
9楼 FlyingSword2008 2011-07-27 11:21发表 [回复]

您好:
我用 make otapackage编译时报一个错误如下:
Traceback (most recent call last):
File "./build/tools/releasetools/ota_from_target_files", line 784, in
main(sys.argv[1:])
File "./build/tools/releasetools/ota_from_target_files", line 760, in main
WriteFullOTAPackage(input_zip, output_zip)
File "./build/tools/releasetools/ota_from_target_files", line 398, in WriteFullOTAPackage
script.WriteRawImage("/boot", "boot.img")
File "/home/zlowram/android/aosp/system/build/tools/releasetools/edify_generator.py", line 241, in WriteRawImage
% {'partition': partition, 'fn': fn})
NameError: global name 'partition' is not defined
make: *** [out/target/product/bravo/htc_bravo-ota-eng.zlowram.zip] Error 1
请问为什么会出现这个错误,怎么解决呢
8楼 weixiangkun 2011-05-27 11:39发表 [回复]

能写一篇文章怎么应用这些源文件生成一个OTA升级包的流程教程吗?新手太多东西看不懂,能有个流程最起码能先用着慢慢熟悉,感谢分享!
7楼 zhong313035502 2011-05-16 10:01发表 [回复]

是的,关键就是这个签名问题了,那如何操作才能使他们一致呢?什么样的步骤,谢谢!
Re: zjujoe 2011-05-17 11:25发表 [回复]

回复 zhong313035502:呵呵。。自己研究吧。我不是专家。只是每天忙忙碌碌的开发者。
6楼 zhong313035502 2011-05-13 17:17发表 [回复]

最后通过java -jar signapk.jar testkey.x509.pem testkey.pk8 org.zip update.zip,放置到sdcard去升级,但都提示signature verification fail,提示升级失败,请帮忙分析下原因,万分感谢!
Re: zjujoe 2011-05-15 15:51发表 [回复]

回复 zhong313035502:你的签名跟目标系统签名不一致。
5楼 zhong313035502 2011-05-13 17:17发表 [回复]

之前在论坛上看到很多类似的自己制作升级包的教程,自己也实际操作了几种,比如按官方的update.zip里面文件放置方式,自己添加相关文件和升级脚本,然后压缩成org.zip文件,
4楼 zhong313035502 2011-05-13 17:16发表 [回复]

zjujoe:
你好,问一个问题,就是采取增量升级的方式,比如我想升级手机里面的某个apk或者so库文件,也是采用ota_from_target_files这个脚本文件来生成update.zip吗?
Re: hygbaby 2011-10-25 11:34发表 [回复]

回复zhong313035502:没错 全包升级以及差分升级都是经由ota_from_target_files此脚本生成
3楼 chongchongzl 2011-04-27 11:21发表 [回复]

make otapackage 没有目标怎么回事。谢谢请指教
Re: zjujoe 2011-04-30 07:01发表 [回复]

回复 chongchongzl: export TARGET_PRODUCT= XXXXX
2楼 yuan1590 2011-04-13 16:39发表 [回复] [引用] [举报]

问一个问题 在哪里建立的recovery.img文件喃?
Re: zjujoe 2011-04-14 09:16发表 [回复]

回复 yuan1590:请研究android编译过程。
1楼 yummy2009 2011-03-07 17:09发表 [回复]

Good !
发表评论