1、前言
最近刚好在做android升级这一块,这是我在工作中总结和参考网上资料整理出来的文档,接触这一块时间也不会很久,纯属是自己的一些体会,如有错误,望大家指点!我工作板子型号是g18ref,采用的是晶晨半导体芯片aml8726mx,源码版本是aml8726mx.0521。当然说到升级,当然就要有升级包,升级包又分为完整包和增量包,所以我们得先从制作升级包说起。然后是Android系统的启动模式分析,Recovery工作原理,在上层选择更新包后是如何进入到Recovery服务的,以及在Recovery服务中具体是怎样处理update.zip升级包的,还有我们的安装脚本updater-script怎样被解析并执行的等一系列问题。下面就这些问题做一些大体的介绍!
2、完整包的制作
(1)cd ~/aml8726mx.0521(源码根目录)
(2). build/envsetup.sh
(3)lunch 10 (选择g18版本)
(4)cd common
(5)make mrproper (清除.o文件及破坏依赖关系,编译时才不会出错,否则有时会出错)
(6)cd ../
(7)make otapackage -j
(8)编译成功的话会在/out/target/product/g18ref/目录下看到g02ref-ota-[date].zip升级包、recovery.img内核文件u-boot.bin文件等,如果有修改了一些文件,然后编译又出错的时候,就删除以下目录内容aml8726mx.0521/out/target/product/g18ref/obj/KERNEL_OBJ/* 这样完整包就制作好了,在升级的时候选中它就可以升级了!
3、增量包的制作
(1)先在源码根目录创建一个目录
cd ~/aml8726mx.0521
mkdir ota
(2)先按正常编译方法编译出我们所需要的.zip包
cd ~/aml8726mx.0521
. build/envsetup.sh
lunch 10
make otapackage -j
通过以上步骤编译后,在以下目录找到我们所需的源码包g18ref-target_files-[date].zip
aml8726mx.0521/out/target/product/g18ref/obj/PACKAGING/target_files_intermediates
将以上编译产生的源码包g18ref-target_files-[date].zip拷贝到之前创建好的ota目录下
并将其改名为g18ref-[date]-old.zip,即用命令
mv g18ref-target_files-[date].zip g18ref-[date]-old.zip
(3)假设apk有更新,这时要编译成增量包,比如说:要加入优酷视频VST_1.0.7_7po.apk
这时可以用手动装载apk或者自动装载apk都可以(见装载apk应用程序)
装载后再编译成.zip包,即:
cd ~/aml8726mx.0521
. build/envsetup.sh
lunch 10
make otapackage -j
通过以上步骤编译后,在以下目录找到我们所需的源码包g18ref-target_files-[date].zip
aml8726mx.0521/out/target/product/g18ref/obj/PACKAGING/target_files_intermediates
将以上编译产生的源码包g18ref-target_files-[date].zip拷贝到之前创建好的ota目录下
并将其改名为g18ref-[date]-new.zip
mv g18ref-target_files-[date].zip g18ref-[date]-new.zip
(4)然后在源码根目录下使用以下命令:
./build/tools/releasetools/ota_from_target_files -i ota/g18ref-[date]-old.zip ota/g18ref-[date]-new.zip ota/g18ref-[date]-update.zip
编译成功后会在ota目录下产生g18ref-[date]-update.zip,这个就是我们所需要的增量包
(5)进入到升级页面下,选择增量包g18ref-[date]-update.zip即可升级
4、装载apk应用程序
刚前面提到了apk的装载,所以这里大体介绍一下。
一、自动加载.apk应用程序(在第一次编译时可采用,若已经有编译过了,还是建议用手动放入)
(1)修改文件:
aml8726mx.0521/device/amlogic/g18ref/g18ref.mk
在以上文件中的
PRODUCT_PACKAGES += \
...
加入VST_1.0.7_7po \
(2)并修改以下文件:
aml8726mx.0521/vendor/amloigc/prebuild/Android.mk
在以上文件中的
prebuilt_apps := \
...
加入VST_1.0.7_7po \
(3)再将所要加入的.apk应用程序放入以下目录中
aml8726mx.0521/vendor/amloigc/prebuild
二、手动放入apk应用程序(至少要编译过一次,才有这个目录)
(1)将所要加入的apk应用程序放入以下目录中即可
aml8726mx.0521/out/target/product/g18ref/system/app
5、完整包详解
一、目录结构
|----boot.img
|----logo.img
|----bootloader.img
|----system/
|----recovery/
|----recovery-from-boot.p
|----etc/
|----install-recovery.sh
|---META-INF/
|----com/
|----google/
|----android/
|----update-binary
|----updater-script
|----android/
|----metadata
|----otacert
|CERT.RSA
|CERT.SF
|MANIFEST.MF
二、目录结构详解
1、boot.img是更新boot分区所需要的文件,这个boot.img主要包括kernel+ramdisk。
2、logo.img是更新logo分区所需要的文件,它主要用于决定升级时显示什么图标。
3、bootloader.img是更新bootloader分区所需要的文件,它主要用于启动内核,为系统准备合适的软硬件环境。
4、system/目录的内容在升级后会放到系统的system分区。主要用来更新系统的一些应用和应用所需的一些库等等。可以将Android源码编译
aml8726mx.0521/out/target/product/g18ref/system/中的所有文件拷贝到这个目录来代替。
5、recovery/目录中的recovery-from-boot.p是boot.img和recovery.img的补丁(patch),主要用来更新recovery分区,其中etc/目录下的install-recovery.sh是其更新脚本。
6、update-binary是一个二进制文件,相当于一个脚本解释器,能够识别updater-script中描述的操作。该文件在Android源码编译后aml8726mx.0521/out/target/product/g18ref/system/bin/updater生成,可将updater重命名为update-binary得到。该文件在更新包中的名字由源码中bootable/recovery/install.cpp宏ASSUMED_UPDATE_BINARY_NAME的值而定。
7、updater-script:此文件是一个脚本文件,具体描述了更新过程。我们可以根据具体情况编写该脚本来适应我们的具体需求。该文件的命名由源码中bootable/recovery/updater/install.c文件中的宏SCRIPT_NAME的值而定。
8、 metadata文件是描述设备信息及环境变量的元数据。主要包括一些编译选项,签名公钥,时间戳以及设备型号等。
9、我们还可以在包中添加userdata目录,来更新系统中的用户数据部分。这部分内容在更新后会存放在系统的/data目录下。
10、update.zip包的签名:update.zip更新包在制作完成后需要对其签名,否则在升级时会出现认证失败的错误提示。
而且签名要使用和目标板一致的加密公钥。加密公钥及加密需要的三个文件在Android源码编译后生成的具体路径为:
out/host/linux-x86/framework/signapk.jar
build/target/product/security/testkey.x509.pem
build/target/product/security/testkey.pk8 。
我们用命令make otapackage制作生成的update.zip包是已签过名的,如果自己做update.zip包时必须手动对其签名。
具体的加密方法:
$ java –jar gingerbread/out/host/linux/framework/signapk.jar –w gingerbread/build/target/product/security/testkey.x509.pem gingerbread/build/target/product/security/testkey.pk8 update.zip update_signed.zip
以上命令在update.zip包所在的路径下执行,其中signapk.jar testkey.x509.pem以及testkey.pk8文件的引用使用绝对路径。update.zip 是我们已经打好的包,update_signed.zip包是命令执行完生成的已经签过名的包。
11、MANIFEST.MF:这个manifest文件定义了与包的组成结构相关的数据。类似Android应用的mainfest.xml文件。
12、CERT.RSA:与签名文件相关联的签名程序块文件,它存储了用于签名JAR文件的公共签名。
13、CERT.SF:这是JAR文件的签名文件,其中前缀CERT代表签名者。另外,在具体升级时,对update.zip包检查时大致会分三步:
①检验SF文件与RSA文件是否匹配。
②检验MANIFEST.MF与签名文件中的digest是否一致。
③检验包中的文件与MANIFEST中所描述的是否一致。
三、ota_from_target_files脚本说明
1、脚本源码(目录:/build/tools/releasetools/ota_from_target_files)
#!/usr/bin/env python
#
# Copyright (C) 2008 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Given a target-files zipfile, produces an OTA package that installs
that build. An incremental OTA is produced if -i is given, otherwise
a full OTA is produced.
Usage: ota_from_target_files [flags] input_target_files output_ota_package
-b (--board_config) <file>
Deprecated.
-k (--package_key) <key> Key to use to sign the package (default is
the value of default_system_dev_certificate from the input
target-files's META/misc_info.txt, or
"build/target/product/security/testkey" if that value is not
specified).
For incremental OTAs, the default value is based on the source
target-file, not the target build.
-i (--incremental_from) <file>
Generate an incremental OTA using the given target-files zip as
the starting build.
-w (--wipe_user_data)
Generate an OTA package that will wipe the user data partition
when installed.
-n (--no_prereq)
Omit the timestamp prereq check normally included at the top of
the build scripts (used for developer OTA packages which
legitimately need to go back and forth).
-e (--extra_script) <file>
Insert the contents of file at the end of the update script.
-a (--aslr_mode) <on|off>
Specify whether to turn on ASLR for the package (on by default).
"""
import sys
if sys.hexversion < 0x02040000:
print >> sys.stderr, "Python 2.4 or newer is required."
sys.exit(1)
import copy
import errno