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

作者: 宋立新

Emailzjujoe@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)

  1. 1073#Dependingonthevariousimagesguaranteesthattheunderlying
  2. 1074#directoriesareup-to-date.
  3. 1075$(BUILT_TARGET_FILES_PACKAGE):/
  4. 1076$(INSTALLED_BOOTIMAGE_TARGET)/
  5. 1077$(INSTALLED_RADIOIMAGE_TARGET)/
  6. 1078$(INSTALLED_RECOVERYIMAGE_TARGET)/
  7. 1079$(INSTALLED_FACTORYIMAGE_TARGET)/
  8. 1080$(INSTALLED_SYSTEMIMAGE)/
  9. 1081$(INSTALLED_USERDATAIMAGE_TARGET)/
  10. 1082$(INSTALLED_SECROIMAGE_TARGET)/
  11. 1083$(INSTALLED_ANDROID_INFO_TXT_TARGET)/
  12. 1084$(built_ota_tools)/
  13. 1085$(APKCERTS_FILE)/
  14. 1086$(HOST_OUT_EXECUTABLES)/fs_config/
  15. 1087|$(ACP)
  16. 1088@echo"Packagetargetfiles:$@"
  17. 1089$(hide)rm-rf$@$(zip_root)
  18. 1090$(hide)mkdir-p$(dir$@)$(zip_root)
  19. 1091@#Componentsoftherecoveryimage
  20. 1092$(hide)mkdir-p$(zip_root)/RECOVERY
  21. 1093$(hide)$(callpackage_files-copy-root,/
  22. 1094$(TARGET_RECOVERY_ROOT_OUT),$(zip_root)/RECOVERY/RAMDISK)
  23. 1095ifdefINSTALLED_KERNEL_TARGET
  24. 1096$(hide)$(ACP)$(INSTALLED_KERNEL_TARGET)$(zip_root)/RECOVERY/kernel
  25. 1097$(hide)$(ACP)$(recovery_ramdisk)$(zip_root)/RECOVERY/ramdisk
  26. 1098endif
  27. 1099ifdefINSTALLED_2NDBOOTLOADER_TARGET
  28. 1100$(hide)$(ACP)/
  29. 1101$(INSTALLED_2NDBOOTLOADER_TARGET)$(zip_root)/RECOVERY/second
  30. 1102endif
  31. 1103ifdefBOARD_KERNEL_CMDLINE
  32. 1104$(hide)echo"$(BOARD_KERNEL_CMDLINE)">$(zip_root)/RECOVERY/cmdline
  33. 1105endif
  34. 1106ifdefBOARD_KERNEL_BASE
  35. 1107$(hide)echo"$(BOARD_KERNEL_BASE)">$(zip_root)/RECOVERY/base
  36. 1108endif
  37. 1109@#Componentsofthefactoryimage
  38. 1110$(hide)mkdir-p$(zip_root)/FACTORY
  39. 1111$(hide)$(callpackage_files-copy-root,/
  40. 1112$(TARGET_FACTORY_ROOT_OUT),$(zip_root)/FACTORY/RAMDISK)
  41. 1113ifdefINSTALLED_KERNEL_TARGET
  42. 1114$(hide)$(ACP)$(INSTALLED_KERNEL_TARGET)$(zip_root)/FACTORY/kernel
  43. 1115endif
  44. 1116ifdefINSTALLED_2NDBOOTLOADER_TARGET
  45. 1117$(hide)$(ACP)/
  46. 1118$(INSTALLED_2NDBOOTLOADER_TARGET)$(zip_root)/FACTORY/second
  47. 1119endif
  48. 1120ifdefBOARD_KERNEL_CMDLINE
  49. 1121$(hide)echo"$(BOARD_KERNEL_CMDLINE)">$(zip_root)/FACTORY/cmdline
  50. 1122endif
  51. 1123ifdefBOARD_KERNEL_BASE
  52. 1124$(hide)echo"$(BOARD_KERNEL_BASE)">$(zip_root)/FACTORY/base
  53. 1125endif
  54. 1126@#Componentsofthebootimage
  55. 1127$(hide)mkdir-p$(zip_root)/BOOT
  56. 1128$(hide)$(callpackage_files-copy-root,/
  57. 1129$(TARGET_ROOT_OUT),$(zip_root)/BOOT/RAMDISK)
  58. 1130ifdefINSTALLED_KERNEL_TARGET
  59. 1131$(hide)$(ACP)$(INSTALLED_KERNEL_TARGET)$(zip_root)/BOOT/kernel
  60. 1132$(hide)$(ACP)$(INSTALLED_RAMDISK_TARGET)$(zip_root)/BOOT/ramdisk
  61. 1133endif
  62. 1134ifdefINSTALLED_2NDBOOTLOADER_TARGET
  63. 1135$(hide)$(ACP)/
  64. 1136$(INSTALLED_2NDBOOTLOADER_TARGET)$(zip_root)/BOOT/second
  65. 1137endif
  66. 1138ifdefBOARD_KERNEL_CMDLINE
  67. 1139$(hide)echo"$(BOARD_KERNEL_CMDLINE)">$(zip_root)/BOOT/cmdline
  68. 1140endif
  69. 1141ifdefBOARD_KERNEL_BASE
  70. 1142$(hide)echo"$(BOARD_KERNEL_BASE)">$(zip_root)/BOOT/base
  71. 1143endif
  72. 1144$(hide)$(foreacht,$(INSTALLED_RADIOIMAGE_TARGET),/
  73. 1145mkdir-p$(zip_root)/RADIO;/
  74. 1146$(ACP)$(t)$(zip_root)/RADIO/$(notdir$(t));)
  75. 1147@#Contentsofthesystemimage
  76. 1148$(hide)$(callpackage_files-copy-root,/
  77. 1149$(SYSTEMIMAGE_SOURCE_DIR),$(zip_root)/SYSTEM)
  78. 1150@#Contentsofthedataimage
  79. 1151$(hide)$(callpackage_files-copy-root,/
  80. 1152$(TARGET_OUT_DATA),$(zip_root)/DATA)
  81. 1153@#ExtracontentsoftheOTApackage
  82. 1154$(hide)mkdir-p$(zip_root)/OTA/bin
  83. 1155$(hide)$(ACP)$(INSTALLED_ANDROID_INFO_TXT_TARGET)$(zip_root)/OTA/
  84. 1156$(hide)$(ACP)$(PRIVATE_OTA_TOOLS)$(zip_root)/OTA/bin/
  85. 1157@#Filesthatdonotendupinanyimages,butarenecessaryto
  86. 1158@#buildthem.
  87. 1159$(hide)mkdir-p$(zip_root)/META
  88. 1160$(hide)$(ACP)$(APKCERTS_FILE)$(zip_root)/META/apkcerts.txt
  89. 1161$(hide)echo"$(PRODUCT_OTA_PUBLIC_KEYS)">$(zip_root)/META/otakeys.txt
  90. 1162$(hide)echo"$(PRIVATE_RECOVERY_API_VERSION)">$(zip_root)/META/recovery-api-version.txt
  91. 1163$(hide)echo"blocksize$(BOARD_FLASH_BLOCK_SIZE)">$(zip_root)/META/imagesizes.txt
  92. 1164$(hide)echo"boot$(callimage-size-from-data-size,$(BOARD_BOOTIMAGE_PARTITION_SIZE))">>$(zip_root)/META/imagesizes.txt
  93. 1165$(hide)echo"recovery$(callimage-size-from-data-size,$(BOARD_RECOVERYIMAGE_PARTITION_SIZE))">>$(zip_root)/META/imagesizes.txt
  94. 1166$(hide)echo"system$(callimage-size-from-data-size,$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))">>$(zip_root)/META/imagesizes.txt
  95. 1167$(hide)echo"secro$(callimage-size-from-data-size,$(BOARD_SECROIMAGE_PARTITION_SIZE))">>$(zip_root)/META/imagesizes.txt
  96. 1168$(hide)echo"userdata$(callimage-size-from-data-size,$(BOARD_USERDATAIMAGE_PARTITION_SIZE))">>$(zip_root)/META/imagesizes.txt
  97. 1169$(hide)echo"$(tool_extensions)">$(zip_root)/META/tool-extensions.txt
  98. 1170@#Zipeverythingup,preservingsymlinks
  99. 1171$(hide)(cd$(zip_root)&&zip-qry../$(notdir$@).)
  100. 1172@#Runfs_configonallthesystemfilesinthezip,andsavetheoutput
  101. 1173$(hide)zipinfo-1$@|awk-F/'BEGIN{OFS="/"}/^SYSTEM///{$$1="system";print}'|$(HOST_OUT_EXECUTABLES)/fs_config>$(zip_root)/META/filesystem_config.txt
  102. 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)

  1. 1186name:=$(TARGET_PRODUCT)
  2. 1187ifeq($(TARGET_BUILD_TYPE),debug)
  3. 1188name:=$(name)_debug
  4. 1189endif
  5. 1190name:=$(name)-ota-$(FILE_NAME_TAG)
  6. 1191
  7. 1192INTERNAL_OTA_PACKAGE_TARGET:=$(PRODUCT_OUT)/$(name).zip
  8. 1193
  9. 1194$(INTERNAL_OTA_PACKAGE_TARGET):KEY_CERT_PAIR:=$(DEFAULT_KEY_CERT_PAIR)
  10. 1195
  11. 1196ifeq($(TARGET_OTA_SCRIPT_MODE),)
  12. 1197#defaultto"auto"
  13. 1198$(INTERNAL_OTA_PACKAGE_TARGET):scriptmode:=auto
  14. 1199else
  15. 1200$(INTERNAL_OTA_PACKAGE_TARGET):scriptmode:=$(TARGET_OTA_SCRIPT_MODE)
  16. 1201endif
  17. 1202
  18. 1203$(INTERNAL_OTA_PACKAGE_TARGET):$(BUILT_TARGET_FILES_PACKAGE)$(OTATOOLS)
  19. 1204@echo"PackageOTA:$@"
  20. 1205$(hide)./build/tools/releasetools/ota_from_target_files/
  21. 1206-m$(scriptmode)/
  22. 1207-p$(HOST_OUT)/
  23. 1208-k$(KEY_CERT_PAIR)/
  24. 1209$(BUILT_TARGET_FILES_PACKAGE)$@

核心是一个python脚本: ota_from_target_files,它以前一步骤生成的ZIP包作为输入,生成可用于OTA升级的zip包。 具体内容我们后文继续分析。

更多相关文章

  1. Android学习五 网络编程与handler消息机制
  2. Android(安卓)IT资讯网络阅读器应用源码
  3. 获取Nexus系列手机驱动(用于编译Android(安卓)ROM的驱动)
  4. Eclipse的项目迁移到Android(安卓)Studio的方法。
  5. Android免root查看数据库内容
  6. Android通过Service编程实现短信监听,通过Toast显示收到的短信的
  7. Android(安卓)应用程序之间内容分享详解(二)
  8. android列表【android开发记录片】android下实现圆角列表布局控
  9. Android(安卓)pppd_gprs脚本启动过程

随机推荐

  1. java android客户端SSL通信 遇到的几个报
  2. android 常见分辨率(mdpi、hdpi 、xhdpi、
  3. Android字体加粗
  4. 2-8 Android(安卓)简单介绍 (一)
  5. Android重力感应实现方式简介
  6. Android调试问题集锦
  7. Android(安卓)轻松实现语音识别
  8. 利用HTML5开发Android
  9. Android面试题收集
  10. Android美化EditText