Android 8.0 recovery 流程分析

本文深入分析了Android 8.0非A/B模式下的recovery流程,包括加载分区表、解析参数、设置recovery界面、执行命令、等待用户输入以及结束recovery的步骤。此外,还概述了启动recovery的三种方式(ADB重启、系统升级接口、按键组合)及一些相关知识点。
摘要由CSDN通过智能技术生成

这里主要分析non A/B模式下的recovery流程
A/B模式下的recovery在boot中
后续会不断补充,如果有疏漏或者错误的地方,请指出,共同学习,谢谢!

一、流程分析

首先列出recovery流程的几个重要点,接着会详细分析

  1. 加载recovery.fstab分区表
  2. 解析传入的参数
  3. recovery界面相关的设置
  4. 执行命令
  5. 如果没有命令,等待用户输入
  6. 结束recovery

1.加载分区表

首先看recovery.cpp的main函数,后面会解释为什么

[recovery.cpp]
int main(int argc, char **argv) {
    //因为这个时候还没启动logcat,这里应该是设置将log打印到屏幕上和recovery.log中
    android::base::InitLogging(argv, &UiLogger);
    //下面是加载pmsg log文件
    // Take last pmsg contents and rewrite it to the current pmsg session.
    static const char filter[] = "recovery/";
    // Do we need to rotate?
    //这里应该和重命名log文件有关
    bool doRotate = false;

    __android_log_pmsg_file_read(
        LOG_ID_SYSTEM, ANDROID_LOG_INFO, filter,
        logbasename, &doRotate);
    // Take action to refresh pmsg contents
    __android_log_pmsg_file_read(
        LOG_ID_SYSTEM, ANDROID_LOG_INFO, filter,
        logrotate, &doRotate);
    //看注释,这里是启动迷你版的adbd,为了使用adb sideload命令
    if (argc == 2 && strcmp(argv[1], "--adbd") == 0) {
        minadbd_main();
        return 0;
    }
    //猜测这里是把log输出重定向到/tmp/recovery.log
    redirect_stdio(TEMPORARY_LOG_FILE);
    //加载recovery.fstab并建立分区表信息,在etc/目录下,recovery模式连adb可以看到
    load_volume_table();
    //从上面建立的分区表信息中读取是否有cache分区,因为log等重要信息都存在cache分区里
    has_cache = volume_for_path(CACHE_ROOT) != nullptr;
    ..........
}

详细看下是如何加载分区表的

[roots.cpp]
void load_volume_table()
{
    int i;
    int ret;

    fstab = fs_mgr_read_fstab_default();
    if (!fstab) {
        LOG(ERROR) << "failed to read default fstab";
        return;
    }
    //将对应的信息加入到一条链表中
    ret = fs_mgr_add_entry(fstab, "/tmp", "ramdisk", "ramdisk");
    if (ret < 0 ) {
        LOG(ERROR) << "failed to add /tmp entry to fstab";
        fs_mgr_free_fstab(fstab);
        fstab = NULL;
        return;
    }

    printf("recovery filesystem table\n");
    printf("=========================\n");
    //在last_log中打印分区表信息
    //打印的顺序是:
    //编号  |  挂载节点  |  文件系统类型  |  块设备  |  长度
    for (i = 0; i < fstab->num_entries; ++i) {
        Volume* v = &fstab->recs[i];
        printf("  %d %s %s %s %lld\n", i, v->mount_point, v->fs_type,
               v->blk_device, v->length);
    }
    printf("\n");
}

跟踪fs_mgr_read_fstab_default

[fs_mgr_fstab.cpp]
struct fstab *fs_mgr_read_fstab_default()
{
    std::string hw;
    std::string default_fstab;

    //下面应该是去其它位置查询fstab文件,由于/sbin/recovery是有的,这里default_fstab是"/etc/recovery.fstab"
    //A/B和non A/B下fstab文件是不同的
    if (access("/sbin/recovery", F_OK) == 0) {
        default_fstab = "/etc/recovery.fstab";
    } else if (fs_mgr_get_boot_config("hardware", &hw)) {  // normal boot
        for (const char *prefix : {
  "/odm/etc/fstab.","/vendor/etc/fstab.", "/fstab."}) {
            default_fstab = prefix + hw;
            if (access(default_fstab.c_str(), F_OK) == 0) break;
        }
    } else {
        LWARNING << __FUNCTION__ << "(): failed to find device hardware name";
    }

    
  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值