zoukankan      html  css  js  c++  java
  • android recovery介绍

    概要

    recovery.img=recovery_ramdisk.img+kernel。recovery模式有自己的根文件系统,与normal根文件系统不同。相应的有自己的
    init.rc以及fstab文件。
    recovery模块功能:恢复出厂设置和升级。
    recovery升级方式有两种如下所示,不管哪种方式都会重启进入recovery模式启动执行init.rc里的recovery服务执行安装升级。

    • 离线升级即手动拷贝升级包到SD卡通过settings-->About phone-->System Update-->选择从SD卡升级。
    • 在线升级即OTA (over the air)。用户通过在线下载升级包到本地。

    recovery模式工作原理

    recovery模式涉及三个实体:main system、recovery、bootloader。
    recovery模式通信接口:

    1. cache分区
    	/cache/recovery/command文件, 此文件保存了main system传给recovery的命令行,每一行就是一条命令。
    	--wipe_cache   //擦除cache分区
    	-wipe_data    //擦除用户数据。擦除data分区时必须要擦除cache分区
    	--update_package=root:path   // Main system将这条命令写入时,代表系统需要升级,在进入Recovery模式后,将该文件中的命令读取并写入BCB中,然后进行相应的更新update.zip包的操作
        	--send_intent=anystring   //在Recovery结束时在finish_recovery函数中将定义的intent字符串作为参数传进来,并写入到/cache/recovery/intent中
    	/cache/recovery/log文件,	//Recovery模式在工作中的log打印
    	/cache/recovery/intent文件,//Recovery传递给Main system的信息
    
    1. MISC分区BCB
    	      struct bootloader_message{
                           char command[32];
                           char status[32];
                           char recovery[1024];
    	}
    	recovery字段格式为:
            “recovery
    
             <recovery command>
    
             <recovery command>
    
             <recovery command>”
    	就是一个字符串,必须以recovery
    开头,否则这个字段的所有内容域会被忽略。同时每条指令都是以“
    ”结尾,每条指令各占一行。
    	“recovery
    ”之后的部分,是/cache/recovery/command支持的命令。可以将其理解为Recovery操作过程中对命令操作的备份。
    	Recovery操作过程为:先读取BCB然后读取/cache/recovery/command,然后将二者重新写回BCB,这样在进入Main system之前,确保操作被执行。
    	在操作之后进入Main system之前,Recovery又会清空BCB的command域和recovery域,这样确保重启后不再进入Recovery模式。
    

    recovery启动流程

    1. recovery bin 启动流程
      bootloader检测到recovery模式后会加载recovery.img启动,recovery.img类似于boot.img,包含标准kernel和recovery特有的根文件系统。init进程解析执行bootable/recovery/etc/init.rc。init.rc启动recovery服务。

    2. recovery main流程

      • 加载recovery.fstab分区表

      • 获取recovery 命令:get_args()
        获取命令位置的优先级是:命令行参数、misc分区、cache/recovery/command。
        如果从命令行获取到命令,就不会再解析misc和cache命令,如果从misc分区获取到命令,就不会再解析cache/recovery/command文件。
        最后把命令又更新到misc分区 BCB块的recovery字段,把boot-recovery字符串写到BCB块的command字段。系统重启又进入到recovery。

      • recovery界面设置

      • 执行命令

      • 如果没有命令,等待用户输入

      • finish_recovery

    recovery debug

    1. recovery模式使用adb
    bootable/recovery/etc/init.rc
    on property:ro.debuggable=1
        write /sys/class/android_usb/android0/enable 1
        start adbd
    
    userdebug或eng版本,启动adbd。
    adb shell命令需要mount system。
    其它adb命令可以使用:
    adb devices
    
    adb root
    adb push/pull
    
    1. recovery模式下log 打印
    有两种方式打印log:printf 和 ui->print
    ui->print:t调用screen_ui的print函数,将信息显示在屏幕上
    printf输出到stdout,stdout重定向到下面文件:
    
    freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL);
    freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
    static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log";
    
    recovery输出log到/tmp/recovery.log文件,finish_recovery()函数把/tmp里临时日志拷贝到cache分区:
    static const char *LAST_LOG_FILE = "/cache/recovery/last_log";
    static const char *LAST_INSTALL_FILE = "/cache/recovery/last_install";
    copy_log_file(TEMPORARY_LOG_FILE, LOG_FILE, true);
    copy_log_file(TEMPORARY_LOG_FILE, LAST_LOG_FILE, false);
    copy_log_file(TEMPORARY_INSTALL_FILE, LAST_INSTALL_FILE, false);
    
    /cache/recovery/last_log:recovery log
    /cache/recovery/last_install:最后一次更新OTA升级包的日志
    

    android系统boot mode

    1. 组合键
      VolumeUp + Power进入Recovery
      VolumeDown + Power组合键,进入BootMenu菜单(fastboot mode),选择进入Recovery

    2. BCB (Bootloader Control Block)
      启动过程中用户没有按下任何组合键,bootloader读取MISC分区的BCB,BCB存放启动命令。
      struct bootloader_message{
      char command[32]; //存放不同的启动命令
      char status[32]; //升级完成后存放执行结果
      char recovery[1024]; //存放/cache/recovery/command
      };

      1:command=="boot-recovery"时,系统会进入Recovery模式。Recovery服务会具体根据/cache/recovery/command中的命令执行相应的操作(例如,升级update.zip或擦除cache、data等)。
      2:command为空时,即没有任何命令,系统会进入正常的启动,最后进入主系统(main system)

    参考文档

    https://www.cnblogs.com/xiaolei-kaiyuan/p/5456227.html
    https://blog.csdn.net/ShuttleCheng/article/details/79186756

  • 相关阅读:
    【源码剖析】HashMap1.7 详解
    友链
    P4747 [CERC2017]Intrinsic Interval
    Educational Codeforces Round 97 简要题解
    CF908D New Year and Arbitrary Arrangement(期望 dp)
    一个方便的自定义注解,管理实体类
    Leetcode 657 机器人能否回到原点
    Leetcode 695 岛屿的最大面积 二维平面DFS
    WebSocket 的简单用例
    俄罗斯方块JAVA
  • 原文地址:https://www.cnblogs.com/bobfly1984/p/14090265.html
Copyright © 2011-2022 走看看