搜索
您的当前位置:首页正文

Recovery??

来源:意榕旅游网
目 录

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.

目的 ................................................................................................... 错误!未定义书签。 适用范围 ........................................................................................... 错误!未定义书签。 参考文档 ........................................................................................... 错误!未定义书签。 缩写 ................................................................................................... 错误!未定义书签。 名词定义 ........................................................................................... 错误!未定义书签。 Recovery简介 .................................................................................................................... 2 Android手机一般有三种启动模式 ................................................................................. 2 Recovery涉及到的其他系统及文件 ................................................................................ 2 Recovery Case .................................................................................................................... 3 “apply update from sdcard”功能详解 ............................................................................ 4 Recovery模式流程 ............................................................................................................ 6 Recovery模式流程图 (网络上的参考流程) ................................................................... 9

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

\\n

其中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):

|\e\\ |-- 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 ar0922e_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 //读取系统资源和信息

nd

o get_bootloader_message():bootloader.c //read mtdblock0(misc partition) 2 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\

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)// o 1) do nothing but reboot

o 2) install_package('SDCARD:update.zip')

o 3) erase_root() → format_root_device() DATA/CACHE o 4) only erase the CACHE

o

//****************************固件升级部分详述**********************start //

ForUpdateFirmwareFn():\\bootable\\recovery\er\\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(boot.command, \"update-firmware\“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 //

reboot(RB_AUTOBOOT); // Perform a hard reset now//

//-----在与Recovery配合update-firmware 的boot函数----start//

 obm_update():\\boot\\\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//

o

//****************************固件升级部分详述**********************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后的行为流程。

因篇幅问题不能全部显示,请点此查看更多更全内容

Top