AndroidRecovery模式

(muddogxp原创,转载请注明)

http://blogold.chinaunix.net/u/14459/showart_1911144.html

Recovery简介

Android利用Recovery模式,进行恢复出厂设置,OTA升级,patch升级及firmware升级。

升级一般通过运行升级包中的META-INF/com/google/android/update-script脚本来执行自定义升级,脚本中是一组recovery系统能识别的UI控制,文件系统操作命令,例如write_raw_image(写FLASH分区),copy_dir(复制目录)。该包一般被下载至SDCARDCACHE分区下。如果对该包内容感兴趣,可以从http://forum.xda-developers.com/showthread.php?t=442480下载JF升级包来看看。

升级中还涉及到包的数字签名,签名方式和普通JAR文件签名差不错。公钥会被硬编译入recovery,编译时生成在:out/target/product/XX/obj/PACKAGING/ota_keys_inc_intermediates/keys.inc

G1中的三种启动模式

MAGIC KEY:

  • camera +powerbootloader模式,ADP里则可以使用fastboot模式

  • home + powerrecovery模式

  • 正常启动

Bootloader正常启动,又有三种方式,按照BCBBootloaderControl Block,下节介绍)中的command分类:

  • command == 'boot-recovery'→ 启动recovery.imgrecovery模式

  • command =='update-radio/hboot' →更新firmwarebootloader)

  • 其他 → 启动boot.img

Recovery涉及到的其他系统及文件

  • CACHE分区文件

    Recovery工具通过NANDcache分区上的三个文件和主系统打交道。主系统(包括恢复出厂设置和OTA升级)可以写入recovery所需的命令,读出recovery过程中的LOGintent

    • /cache/recovery/commandrecovery命令,由主系统写入。所有命令如下:

      • --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/logrecovery过程日志,由主系统读出

    • /cache/recovery/intentrecovery输出的intent

  • MISC分区内容

    Bootloader Control Block(BCB) 存放recoverybootloader message。结构如下:

    structbootloader_message {

      charcommand[32];

      charstatus[32]; //未知用途

      charrecovery[1024];

    };

    • command可以有以下两个值

      boot-recovery”:标示recovery正在进行,或指示bootloader应该进入recoverymode

      update-hboot/radio”:指示bootloader更新firmware

    • recovery内容

      recovery\n

      <recoverycommand>\n

      <recoverycommand>

      其中recoverycommandCACHE:/recovery/command命令


两种RecoveryCase

  • FACTORYRESET(恢复出厂设置)

  1. 用户选择“恢复出厂设置”

  2. 设置系统将"--wipe_data"命令写入/cache/recovery/command

  3. 系统重启,并进入recover模式(/sbin/recovery

  4. get_args()"boot-recovery""--wipe_data"写入BCB

  5. erase_root()格式化(擦除)DATA分区

  6. erase_root()格式化(擦除)CACHE分区

  7. finish_recovery()擦除BCB

  8. 重启系统

  • OTAINSTALLOTA升级)

  1. 升级系统下载OTA包到/cache/some-filename.zip

  2. 升级系统写入recovery命令"--update_package=CACHE:some-filename.zip"

  3. 重启,并进入recovery模式

  4. get_args()"boot-recovery""--update_package=..."写入BCB

  5. install_package()作升级

  6. finish_recovery()擦除BCB

  7. **如果安装包失败**prompt_and_wait() 等待用户操作,选择ALT+SALT+W升级或恢复出厂设置

  8. main()调用maybe_install_firmware_update()

    1. 如果包里有hboot/radiofirmware则继续,否则返回

    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模式流程


/init init.rc/sbin/recovery

main():recovery.c


  • ui_init():ui.cUI initialize

    • gr_init():minui/graphics.cset tty0 to graphicmode, open fb0]

    • ev_init():minui/events.c [open /dev/input/event*]

    • res_create_surface:minui/resource.c [create surfaces for all bitmaps used later, include icons, bmps]

    • create2 threads: progress/input_thread [create progress show and inputevent handler thread]

  • get_args():recovery.c

    • get_bootloader_message():bootloader.c [read mtdblock0(misc partition) 2nd page forcommandline]

    • checkif nand misc partition has boot message. If yes, fill argc/argv.

    • Ifno, get arguments from /cache/recovery/command, and fill argc/argv.

    • set_bootloader_message():bootloader.c [set bootloader message back to mtdblock0]

  • Parserargv[] filled above

  • register_update_commands():commands.c[ register all commands with name and hook function ]

    • registerCommand():commands.c

      • Registercommand with name, hook, type, cookie.

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

    • registerFunction():commands.c

      • Registerfunction with name, hook, cookie.

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

  • install_package():

    • translate_root_path():roots.c [ "SYSTEM:lib" and turns it into a string like"/system/lib", translate the updater.zip path ]

    • mzOpenZipArchive():zip.c [ open updater.zip file (uncompass) ]

    • handle_update_package():install.c

      • verify_jar_signature():verifier.c [ verify signature with keys.inc key; verify manifest and zippackage archive ]

        • verifySignature() [ verify the signature file: CERT.sf/rsa. ]

          • digestEntry():verifier.c [ get SHA-1 digest of CERT.sf file ]

          • RSA_verify(publickey:keys.inc, signature:CERT.rsa, CERT.sf's digest):libc/rsa.c [ Verify a 2048 bit RSA PKCS1.5 signature against an expectedSHA-1 hash. Use public key to decrypt the CERT.rsa to getoriginal SHA digest, then compare to digest of CERT.sf ]

        • verifyManifest() [ Get manifest SHA1-Digest from CERT.sf. Then do digest toMANIFEST.MF. Compare them ]

        • verifyArchive() [ verify all the files in update.zip with digest listed inMANIFEST.MF ]

      • find_update_script():install.c[ find META-INF/com/google/android/update-script 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 ]

  • eraseDATA/CACHE partition

  • prompt_and_wait():recovery.c [ wait for user input: 1) reboot 2) update.zip 3) wipe data ]

    • ui_key_xxxget ALT+x keys

    • 1)do nothing

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

    • 3)erase_root()format_root_device() DATA/CACHE

  • may_install_firmware_update():firmware.c [ remember_firmware_update() is called by write_hboot/radio_imagecommand, it stores the bootloader image to CACHE partition, andwrite update-hboot/radio command to MISC partition for bootloadermessage to let bootloader update itself after reboot ]

    • set_bootloader_message()

    • write_update_for_bootloader():bootloader.c[ write firmware image into CACHE partition with update_header,busyimage and failimage ]

  • finish_recovery():recovery.c [ clear the recovery command and prepare to boot a (hopefullyworking) system, copy our log file to cache as well (for the systemto read), and record any intent we were asked to communicate back tothe system. ]

  • reboot()


Recovery模式流程图

以下流程图绘制了系统从启动加载bootloader后的行为流程。








Android Recovery模式_第1张图片



更多相关文章

  1. Android调用系统默认浏览器访问的方法
  2. Android2.1系统在TOP6410上完美运行
  3. Android调用系统摄像头拍照并剪裁压缩
  4. Android AppWidget系统框架
  5. Android之Input子系统事件分发流程
  6. android通过读取系统属性设置字体缩放的默认值
  7. android 5.1 添加reboot 飞行模式 silent
  8. android应用程序跳转到系统的各个设置页面
  9. Android系统自带的常用数据库

随机推荐

  1. Android内存泄露及分析
  2. android 下拉窗口菜单的实现(popupwindow)
  3. Android NDK开发下使用C/C++的几个概念
  4. Android面试题(27)-android的事件分发机制
  5. android的语言切换-应用程序 根据 不同的
  6. android三级缓存详解
  7. android连接onenet之获取onenet数据流和
  8. android:异步任务asyncTask介绍及异步任
  9. Android相机实时自动对焦的完美实现(带源
  10. android UI进阶之仿iphone的tab效果