最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

Recovery模式

来源:动视网 责编:小OO 时间:2025-09-25 06:59:06
文档

Recovery模式

目录1.目的42.适用范围43.参考文档44.缩写45.名词定义46.Recovery简介57.Android手机一般有三种启动模式58.Recovery涉及到的其他系统及文件59.RecoveryCase610.“applyupdatefromsdcard”功能详解711.Recovery模式流程912.Recovery模式流程图(网络上的参考流程)121.Recovery简介Android利用Recovery模式,进行恢复出厂设置,OTA升级,patch升级及firmware升级。升级一般
推荐度:
导读目录1.目的42.适用范围43.参考文档44.缩写45.名词定义46.Recovery简介57.Android手机一般有三种启动模式58.Recovery涉及到的其他系统及文件59.RecoveryCase610.“applyupdatefromsdcard”功能详解711.Recovery模式流程912.Recovery模式流程图(网络上的参考流程)121.Recovery简介Android利用Recovery模式,进行恢复出厂设置,OTA升级,patch升级及firmware升级。升级一般
目  录

1.    目的    4

2.    适用范围    4

3.    参考文档    4

4.    缩写    4

5.    名词定义    4

6.    Recovery简介    5

7.    Android手机一般有三种启动模式    5

8.    Recovery涉及到的其他系统及文件    5

9.    Recovery Case    6

10.    “apply update from sdcard”功能详解    7

11.    Recovery模式流程    9

12.    Recovery模式流程图 (网络上的参考流程)    12

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

|\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  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显示初始化

ogr_init():minui/graphics.c    //set tty0 to graphic mode, open fb0//

oev_init():minui/events.c      //open /dev/input/event*//

ores_create_surface:minui/resource.c         //create surfaces for all bitmaps used later, include icons, bmps//

ocreate 2 threads: progress/input_thread     //create progress show and input event handler thread//

∙get_args():recovery.c    //读取系统资源和信息

oget_bootloader_message():bootloader.c     //read mtdblock0(misc partition) 2nd page for commandline//

ocheck if nand misc partition has boot message. If yes, fill argc/argv.

oIf no, get arguments from /cache/recovery/command, and fill argc/argv.

oset_bootloader_message():bootloader.c     //set bootloader message back to mtdblock0//

∙Parser argv[] filled above

∙register_update_commands():commands.c     //注册系统命令

oregisterCommand():commands.c 

▪Register command with name, hook, type, cookie.

▪Commands, e.g: assert, delete, copy_dir, symlink, write_raw_image.

oregisterFunction():commands.c

▪Register function with name, hook, cookie.

▪Function, e.g: get_mark, matches, getprop, file_contains

∙install_package():        //升级包安装

otranslate_root_path():roots.c     //EM:lib" and turns it into a string like "/system/lib", translate the updater.zip path//

omzOpenZipArchive():zip.c         //open updater.zip file//

ohandle_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\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

ostrlcpy(boot.command, "update-firmware", sizeof(boot.command));//set the “update-firmware”bootcommand to step to obm_update() in boot//

ocopy_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 //

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

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

∙obm_update():\\boot\\\board\\marvell\brownstone.c    //only in the bootloader//

ommc->block_dev.block_read(0, NTIM_BLK_ADDR, 3, buffer)    //read the boot image from mmcblk0p11 to buffer//

ommc->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后的行为流程。

文档

Recovery模式

目录1.目的42.适用范围43.参考文档44.缩写45.名词定义46.Recovery简介57.Android手机一般有三种启动模式58.Recovery涉及到的其他系统及文件59.RecoveryCase610.“applyupdatefromsdcard”功能详解711.Recovery模式流程912.Recovery模式流程图(网络上的参考流程)121.Recovery简介Android利用Recovery模式,进行恢复出厂设置,OTA升级,patch升级及firmware升级。升级一般
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top