Recovery模式 简介

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

目录
1.目的................................................................................................... 错误!未定义书签。

2.适用范围........................................................................................... 错误!未定义书签。

3.参考文档........................................................................................... 错误!未定义书签。

4.缩写................................................................................................... 错误!未定义书签。

5.名词定义........................................................................................... 错误!未定义书签。

6.Recovery简介 (2)
7.Android手机一般有三种启动模式 (2)
8.Recovery涉及到的其他系统及文件 (3)
9.Recovery Case (4)
10.“apply update from sdcard”功能详解 (5)
11.Recovery模式流程 (8)
12.Recovery模式流程图(网络上的参考流程) (11)
1.Recovery简介
Android利用Recovery模式,进行恢复出厂设置,OTA升级,patch升级及firmware 升级。

升级一般通过运行升级包中的META-INF/com/google/android/update-script脚本来执行自定义升级,脚本中是一组recovery系统能识别的UI控制,文件系统操作命令,例如write_raw_image(写FLASH分区),package_extract_dir(复制目录)。

该包一般被下载至SDCARD和CACHE分区下。

升级中还涉及到包的数字签名,签名方式和普通JAR 文件签名差不多。

公钥会被硬编译入recovery,编译时生成在:
out/target/product/brownstone/obj/PACKAGING/ota_keys_inc_intermediates/keys.inc Recovery功能实现主要需要的模块有:
1、framework/base/core层:Power.java、PowerManager.java和Recoverysystem.java 等上层文件来管理和记录和Recovery有关的上层操作,例如FACTORY RESET和OTA 升级。

2、framework jni层主要有android_os_power.cpp提供上层OTA升级和RBOOT接
口函数。

3、recovery系统层:实现recovery的具体操作。

4、boot下brownstone.c通过判断按键信息和内存信息来确定启动方式,引导进入
recovery模式。

2.Android手机一般有三种启动模式
启动过程中通过boot下得brownstone.c中的magic_test()函数读取按键信息和上层写入的command来确定启动模式
MAGIC KEY:
•menu + power:bootloader进入fastboot模式(也有使用camera + power来实现的)
•home + power:进入recovery模式
•正常启动
Bootloader正常启动,又有三种方式,按照BCB(Bootloader Control Block)的command
分类:
•command == 'boot-recovery' →启动recovery.img进入recovery模式
•command == 'update-firmware' →更新firmware(bootloader)
•其他→启动boot.img
3.Recovery涉及到的其他系统及文件
CACHE分区文件
Recovery 工具通过NAND cache分区上的三个文件和主系统打交道。

主系统(包括恢复出厂设置和OTA升级)可以写入recovery所需的命令,读出recovery过程中的LOG和intent。

/cache/recovery/command:recovery命令,由主系统写入。

所有命令如下:
--send_intent=anystring - write the text out to recovery.intent
--update_package=root:path - verify install an OTA package file
--wipe_data - erase user data (and cache), then reboot
--wipe_cache - wipe cache (but not user data), then reboot
/cache/recovery/log:recovery过程日志,由主系统读出
/cache/recovery/intent:recovery输出的intent
MISC分区内容
Bootloader Control Block (BCB) 存放recovery bootloader message。

结构如下:
struct bootloader_message {
char command[32];
char status[32]; // 还未完全搞懂此变量的用途
char recovery[1024];
};
command可以有以下两个值
“boot-recovery”:标示recovery正在进行,或指示bootloader应该进入recovery mode “update-firmware”:由Recovery写入指示bootloader更新firmware
recovery内容
“recovery\n
<recovery command>\n
<recovery command>”
其中recovery command为CACHE:/recovery/command命令
4.Recovery Case
●FACTORY RESET(恢复出厂设置)
1.用户选择“恢复出厂设置”
2.设置系统将"--wipe_data"命令写入/cache/recovery/command
3.系统重启,并进入recover模式
4.get_args() 将"boot-recovery"和"--wipe_data"写入BCB
5.erase_root() 格式化(擦除)DATA分区
6.erase_root() 格式化(擦除)CACHE分区
7.finish_recovery() 擦除BCB
8.重启系统
●OTA INSTALL(OTA升级)
1.升级系统下载OTA包到/cache/update.zip
2.升级系统写入recovery命令"--update_package=CACHE:update.zip"
3.重启,并进入recovery模式
4.get_args() 将"boot-recovery" 和"--update_package=..." 写入BCB
5.install_package() 作升级
6.finish_recovery() 擦除BCB
7.** 如果安装包失败** prompt_and_wait() 等待用户操作,选择ALT+S或
ALT+W 升级或恢复出厂设置
8.main() 调用maybe_install_firmware_update()
1)如果包里有hboot/radio的firmware则继续,否则返回
2)将"boot-recovery" 和"--wipe_cache" 写入BCB
3)将firmware image写入cache分区
4)将"update-radio/hboot" 和"--wipe_cache" 写入BCB
5)重启系统
6)bootloader自身更新firmware
7)bootloader 将"boot-recovery" 写入BCB
8)erase_root() 擦除CACHE分区
9)清除BCB
9.main() 调用reboot() 重启系统
Recovery 模式
开机过程中按住home+power键
Boot启动过程中判断magic_test()函数读取按键信息,选择启动Recovery
进入Recovery并通过ui显示Recovery功能选项:
"reboot system now", //用于重启系统
"apply update from sdcard", //通过sdcard卡的升级
"wipe data/factory reset", //擦出用户信息恢复出厂设置
"wipe cache partition", //清楚缓存
选择相应功能
系统进入recovery操作
5.“apply update from sdcard”功能详解
从ar0922e_gingerbread_beta1编译好的代码码树中提取一个update.zip所需要的所有资源, 从而最终构建一个可以在android recovery模式下刷机的update.zip包. 建立如下的update目录(用于生成update.zip):
|\update\
|-- META-INF
| `-- com
| `-- google
| `-- android
| |-- update-binary
| `-- updater-script
|-- system
update-binary:二进制文件, 相当于一个脚本解释器, 能识别updater-script 中描述的操作。

该文件由
ar0922e_gingerbread_beta1/out/target/product/brownstone/system/bin/updater重命名所得。

具体用什么名字是由ar0922e_gingerbread_beta1/bootable/recovery/install.c 文件中的宏ASSUMED_UPDATE_BINARY_NAME 的值而定.
updater-script:该文件需要自己根据更新包需要更新的内容自行编写. 具体用什么名字是由ar0922e_gingerbread_beta1/bootable/recovery/updater/updater.c 文件中的宏SCRIPT_NAME 的值而定.(注意: 是updater-script, 而不是update-script).
system: 该目录下放需要更新的内容. 比如,只是需要添加几个系统软件, 则在此目录下添加一个app 目录, 然后把待添加的系统软件copy进来即可. 如果你是要制作一个系统更新包. 那ar0922e_gingerbread_beta1/out/target/product/brownstone/system/ 中的所有文件copy到这个目录里来.
ps:具体添加文件的名字和路径要和updater-script脚本相同。

一个更新包update.zip的制作步骤
$mkdir update ps:在任意目录下,创建一个叫update的目录
$cd upadte ps: 进入该目录
$mkdir –p META-INF/com/google/android/ && mkdir system ps:在update目录下, 创建2个子目录
$cp
ar0922e_gingerbread_beta1/out/target/product/brownstone/system/bin/updater META-INF/ com/google/android/update-binary ps:获取update-binary文件
$cp ar0922e_gingerbread_beta1/out/target/product/brownstone /ramdisk.img ps: 获取更新ramdisk所需要的文件
$vim META-INF/com/google/android/updater-script ps:打开updater-script脚本, 根据需要更新的内容开始编写更新过程.
$zip -qr ../update.zip ./ ps: 编辑完updater-script脚本后, 把update内的所有内容打成一个update.zip包.
$java –jar ar0922e_gingerbread_beta1/out/host/linux-x86/framework/signapk.jar –w ar0 922e_gingerbread_beta1/build/target/product/security/testkey.x509.pem /testkey.pk8 update .zip update_signed.zip
通过这条命令, 会对update.zip包进行签名, 然后输出一个update_signed.zip的签好
名update包. 以此作为最终更新包。

这条命令需要5个条件:
host机需装有java环境, ubuntu上为sun-java5-jdk DEB包
signapk.jar 文件. 在编译好的
ar0922e_gingerbread_beta1/out/host/linux-x86/framework目录下
testkey.x509.pem 在源码的ar0922e_gingerbread_beta1/build/target/product/security 目录下
testkey.pk8 在编译好的ar0922e_gingerbread_beta1/build/target/product/security 目录下
update.zip 没有经过签名的ZIP包.
PS:也可以使用签名工具进行签名。

updater-script 脚本的编写
updater-script 的内容其实为一行一行update-binery能识别的命令序列. 文件
ar0922e_gingerbread_beta1/bootable/recovery/update/install.c 末尾描述了所有可执行命令.部分命令的使用实例:
mount :
eg : mount(“MTD”, “system”, “/system”);
挂在MTD的system分区到文件系统的/system 目录下.
ui_print :
eg : ui_print(“Hello word!”);
在屏幕上打印提示信息.
format :
eg : format(“MTD”, “system”);
格式化MTD的system分区
package_extract_dir :
eg : package_extract_dir(“system”, “/system”);
把update包中system中的内容全部拷贝到文件系统/system下
特别说明:固件升级(boot和radio)和其他软件升级的脚本有所不同,具体在“11.Recovery 模式流程”中详述。

6.Recovery模式流程
/init → init.rc → /sbin/recovery →
main():recovery.c //main入口
∙ui_init():ui.c [UI initialize]//ui显示初始化
o gr_init():minui/graphics.c //set tty0 to graphic mode, open fb0//
o ev_init():minui/events.c //open /dev/input/event*//
o res_create_surface:minui/resource.c //create surfaces for all bitmaps used later, include icons, bmps//
o create 2 threads: progress/input_thread //create progress show and input event handler thread//
∙get_args():recovery.c //读取系统资源和信息
o get_bootloader_message():bootloader.c //read mtdblock0(misc partition) 2nd page for commandline//
o check if nand misc partition has boot message. If yes, fill argc/argv.
o If no, get arguments from /cache/recovery/command, and fill argc/argv.
o set_bootloader_message():bootloader.c //set bootloader message back to mtdblock0//
∙Parser argv[] filled above
∙register_update_commands():commands.c //注册系统命令
o registerCommand():commands.c
▪Register command with name, hook, type, cookie.
▪Commands, e.g: assert, delete, copy_dir, symlink, write_raw_image.
o registerFunction():commands.c
▪Register function with name, hook, cookie.
▪Function, e.g: get_mark, matches, getprop, file_contains ∙install_package(): //升级包安装
o translate_root_path():roots.c //EM:lib" and turns it into a string like "/system/lib", translate the updater.zip path//
o mzOpenZipArchive():zip.c //open updater.zip file//
o handle_update_package():install.c
▪verify_jar_signature():verifier.c //verify signature with keys.inc
key,verify manifest and zip package archive//
▪verifySignature() //verify the signature file: CERT.sf/rsa.//
▪digestEntry():verifier.c //get SHA-1 digest of CERT.sf
file//
▪RSA_verify(public key:keys.inc, signature:CERT.rsa,
CERT.sf's digest):libc/rsa.c //Verify a 2048 bit RSA
PKCS1.5 signature against an expected SHA-1 hash.
Use public key to decrypt the CERT.rsa to get original
SHA digest, then compare to digest of CERT.sf//
▪verifyManifest() //Get manifest SHA1-Digest from CERT.sf.
Then do digest to MANIFEST.MF. Compare them//
▪verifyArchive() //verify all the files in update.zip with digest
listed in MANIFEST.MF//
▪find_update_script():install.c //find META-INF/com/google
/android/updater script//
▪handle_update_script():install.c // read cmds from script file, and do parser, exec//
▪parseAmendScript():amend.c //call yyparse() to parse to
command//
▪exeCommandList():install.c
▪exeCommand():execute.c //call command hook
function//
∙erase DATA/CACHE partition //擦出用户DATA和CACHE
∙prompt_and_wait():recovery.c //wait for user select: 1) reboot 2) update.zip 3) wipe data/factory reset 4)wipe cach)//
o1) do nothing but reboot
o2) install_package('SDCARD:update.zip')
o3) erase_root() → format_root_device() DATA/CACHE
o4) only erase the CACHE
//****************************固件升级部分详述**********************start // ∙ForUpdateFirmwareFn():\bootable\recovery\updater\install.c //is called by “mrvl_for_update_firmware()” command in the updater-script to stores the bootloader image to mmcblk0p11 partition, and write “update-firmware” command to MISC
partition for bootloader message to let bootloader update itself after reboot o strlcpy(mand, "update-firmware", sizeof(mand));//set the “update-firmware”bootcommand to step to obm_update() in boot//
o copy_bootfile_to_device(char* filename, char* devicename, int offset) //copy the file which used to update-firmware from \cache\ to the
mmcblk0p11 ,a partition only used to update-firmware //
o reboot(RB_AUTOBOOT); //Perform a hard reset now//
//-----在与Recovery配合update-firmware 的boot函数----start// ∙obm_update():\boot\uboot\board\marvell\brownstone.c //only in the bootloader// o mmc->block_dev.block_read(0, NTIM_BLK_ADDR, 3, buffer) //read the boot image from mmcblk0p11 to buffer//
o mmc->block_dev.block_write(0, PARTITION_BURN_ADDR, 1, buffer) //burn the boot image to the boot address in emmc from buffer//
//--在与Recovery配合update-firmware 的boot函数--end//
//****************************固件升级部分详述**********************end// ∙finish_recovery():recovery.c //clear the recovery command and prepare to boot a (hopefully working) system, copy our log file to cache as well (for the system to read), and record any intent we were asked to communicate back to the system. // ∙reboot() //
7.Recovery模式流程图
(网络上的参考流程)
以下流程图绘制了系统从启动加载bootloader后的行为流程。

相关文档
最新文档