Recovery简介
Android利用Recovery模式,进行恢复出厂设置,OTA升级,patch升级及firmware升级。
升级一般通过运行升级包中的META-INF/com/google/android/update-script脚本来执行自定义升级,脚本中是一组recovery系统能识别的UI控制,文件系统操作命令,例如write_raw_image(写FLASH分区),copy_dir(复制目录)。该包一般被下载至SDCARD和CACHE分区下。如果对该包内容感兴趣,可以从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 +
    power:bootloader模式,ADP里则可以使用fastboot模式

  • home + power:recovery模式

  • 正常启动


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


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

  • command ==
    'update-radio/hboot' → 更新firmware(bootloader)

  • 其他 → 启动boot.img


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-hboot/radio”:指示bootloader更新firmware

    • recovery内容

      “recovery\n

      \n



      其中recovery
      command为CACHE:/recovery/command命令


两种Recovery
Case

  • FACTORY
    RESET(恢复出厂设置)


  • 用户选择“恢复出厂设置”
  • 设置系统将"--wipe_data"命令写入/cache/recovery/command
  • 系统重启,并进入recover模式(/sbin/recovery)
  • get_args()

    "boot-recovery"和"--wipe_data"写入BCB
  • erase_root()
    格式化(擦除)DATA分区
  • erase_root()
    格式化(擦除)CACHE分区
  • finish_recovery()
    擦除BCB
  • 重启系统

    • OTA
      INSTALL(OTA升级)

  • 升级系统下载
    OTA包到/cache/some-filename.zip
  • 升级系统写入recovery命令"--update_package=CACHE:some-filename.zip"
  • 重启,并进入recovery模式
  • get_args()
    将"boot-recovery"

    "--update_package=..."
    写入BCB
  • install_package()
    作升级
  • finish_recovery()
    擦除 BCB
  • **
    如果安装包失败 **
    prompt_and_wait() 等待用户操作,选择ALT+S或ALT+W
    升级或恢复出厂设置
  • main()
    调用
    maybe_install_firmware_update()
  • 如果包里有hboot/radio的firmware则继续,否则返回

  • "boot-recovery"
    和 "--wipe_cache"
    写入BCB

  • firmware image写入cache分区

  • "update-radio/hboot"
    和 "--wipe_cache"
    写入BCB
  • 重启系统
  • bootloader自身更新firmware
  • bootloader
    将 "boot-recovery"
    写入BCB
  • erase_root()
    擦除CACHE分区
  • 清除
    BCB

  • main()
    调用 reboot()
    重启系统
    Recovery模式流程
    /init
    → init.rc →
    /sbin/recovery →
    main():recovery.c
    • ui_init():ui.c
      [UI initialize]
      • gr_init():minui/graphics.c
        [set tty0 to graphic
        mode, 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]
      • create
        2 threads: progress/input_thread [create progress show and input
        event handler thread]

    • get_args():recovery.c
      • get_bootloader_message():bootloader.c
        [read mtdblock0(misc partition) 2nd page for
        commandline]
      • check
        if nand misc partition has boot message. If yes, fill argc/argv.
      • If
        no, get arguments from /cache/recovery/command, and fill argc/argv.
      • set_bootloader_message():bootloader.c
        [set bootloader message back to mtdblock0]

    • Parser
      argv[] filled above
    • register_update_commands():commands.c
      [ register all commands with name and hook function ]
      • registerCommand():commands.c


        • Register
          command with name, hook, type, cookie.
        • Commands,
          e.g: assert, delete, copy_dir, symlink, write_raw_image.

      • registerFunction():commands.c
        • Register
          function 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 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 dodigest to
            MANIFEST.MF. Compare them ]
          • verifyArchive()
            [ verify all the files in update.zip with digestlisted in
            MANIFEST.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 ]




    • erase
      DATA/CACHE partition
    • prompt_and_wait():recovery.c
      [ wait for user input: 1) reboot 2) update.zip 3) wipe data ]
      • ui_key_xxx
        get 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_image
      command, it stores the bootloader image to CACHE partition, and
      write update-hboot/radio command to MISC partition for bootloader
      message 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 (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()

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




    WIPE 清除手机的信息 就是格式化 然后你在刷你喜欢的ROM。

    5、Wipe——清除
    5-1、Wipe data/factory reset——清除内存数据和缓存数据
    5-2、Wipe Dalvik-cache——清除缓存数据 + ext 分区内数据
    5-3、Wipe SD:ext partition——只清除ext 分区内数据
    5-4、Wipe battery stats——清除电池数据
    5-5、Wipe rotate settings——清除传感器内设置的数据

    分区
    6、Partition sdcard——分区sd 卡
    6-1、Partition SD——自动为sd 卡分区
    6-2、Repair SD:ext——修复ext 分区
    6-3、SD:ext2 to ext3——将ext2 分区转换为ext3 分区(推荐)
    6-4、SD:ext3 to ext4——将ext3 分区转换为ext4 分区(C4 卡不推荐,C6 卡推荐)

    想多了解 请看下面:

    1、Reboot system now——重启

    2、USB-MS toggle——在recovery 模式下直接连接USB,读取你的sd卡,这个非常方便。刷不成的话你还可以往sd卡拷贝别的ROM 进行补救,按小房子退出该模式。非常棒的功能,最近才发现的。2010.05.27.

    3、Backup/Restore——备份和还原
    3-1、Nand backup——Nand 备份
    3-2、Nand + ext backup——Nand 备份(系统和ext 分区一同备份)
    3-3、Nand restore——还原(就是还原3-1、3-2 的最后一次备份)
    3-4、BART backup——BART 备份 (包括系统和ext 分区)
    3-5、BART restore——还原最后一次的BART备份

    Nand 备份类似于系统的备份 而BART 则像是PC 上ghost 的备份。
    Nand 备份 它不会备份ext 分区(就是第二分区 没有分区的可以不管这个)
    所以你的如果app2sd 了 那么装在第二分区的程序用Nand 恢复是办不到的
    BAR T则可以备份到ext 分区 用BART 恢复则可以恢复整个系统 可以使它和你备份前一模一样,不会有一点文件信息的丢失(包括联系人、短信、图片、影音等,所以如果你装的东西比较多,那么备份和恢复会比较慢)

    4、Flash zip from sdcard——从sd卡根目录的.zip ROM 刷机包刷机

    5、Wipe——清除
    5-1、Wipe data/factory reset——清除内存数据和缓存数据
    5-2、Wipe Dalvik-cache——清除缓存数据 + ext 分区内数据
    5-3、Wipe SD:ext partition——只清除ext 分区内数据
    5-4、Wipe battery stats——清除电池数据
    5-5、Wipe rotate settings——清除传感器内设置的数据

    6、Partition sdcard——分区sd 卡
    6-1、Partition SD——自动为sd 卡分区
    6-2、Repair SD:ext——修复ext 分区
    6-3、SD:ext2 to ext3——将ext2 分区转换为ext3 分区(推荐)
    6-4、SD:ext3 to ext4——将ext3 分区转换为ext4 分区(C4 卡不推荐,C6 卡推荐)

    7、Other——其它
    7-1、Fix apk uid mismatches——修复apk 程序
    7-2、Move apps+dalv to SD——移动程序和虚拟缓存到sd 卡(这个可不是 app2sd)
    7-3、Move recovery.log to SD——移动刷机日志文件到sd 卡(执行此操作后,sd 卡根目录会出现一个“recovery.log” 文件 即为刷机日志文件)

    8、Power off——关机

  • 更多相关文章

    1. Android(安卓)的 Recovery 分析
    2. Android(安卓)验证码输入框 连续性粘贴 使用第三方包
    3. (2) 搭建 Android(安卓)系统开发环境
    4. android stdio3.6中textcolor颜色代码大全(个人备份)
    5. 在Mac下编译 android 源代码
    6. android清除缓存并获取大小
    7. Android清理缓存工具类
    8. android 源码下载及问题
    9. 无需root,清除清理安卓,android的cache,缓存

    随机推荐

    1. (两百八十七)Android 更新R aosp源码
    2. 修改源码 自动接听
    3. android视图学习---Android深入浅出之Sur
    4. android中使用AsyncTask做下载进度条
    5. android log日志文件输出
    6. Android Studio获取SHA1证书方法
    7. android自定义支持横竖方向切换seekbar控
    8. Get the Android SDK翻译
    9. Android开发窗口实现半透明效果
    10. Android内存控制