安卓FirstStageMount阶段解析【连载】(一)创建设备Create

本文详细分析了Android系统启动过程中的FirstStageMount阶段,包括FirstStageMain函数、DoFirstStageMount函数以及FirstStageMount类的创建。核心内容涉及Fstab文件的读取,特别是从设备树中读取Fstab信息,并通过ReadFstabFromDt函数解析。文章深入探讨了如何处理fstab_entry,创建FirstStageMount实例,并为后续的分区挂载做准备。

最近在分析安卓的FirstStageMount阶段,这部分代码量还是挺大的,而且不容易理解,所以记录一下自己学习的心得和成果。本文都是基于Android S来分析的。

源码地址如下:Android S源码

1.引言

根据安卓的启动流程,从Kernel进入到Init进程后,首先会执行FirstStageMain,里面又分为第一阶段挂在DoFirstStageMount和第二部分selinux_setup配置,这个系列的文章会分析DoFirstStageMount所有的流程;

// 路径:/system/core/init/first_stage_init.cpp
int FirstStageMain(int argc, char** argv) {
   
   
	// ...
    if (!DoFirstStageMount(!created_devices)) {
   
   
        LOG(FATAL) << "Failed to mount required partitions early ...";
    }
  	// ...
}

2.开始DoFirstStageMount

// 路径: /system/core/init/first_stage_mount.cpp
// 在设备树中挂载由fstab文件指定的分区
bool DoFirstStageMount(bool create_devices) {
   
   
	// -----------------------------第一部分-----------------------------
    auto fsm = FirstStageMount::Create();
    if (!fsm.ok()) {
   
   
        LOG(ERROR) << "Failed to create FirstStageMount " << fsm.error();
        return false;
    }
	
	// ...这边是判断之前是否创建过devices,可以打印Log看一下,显然之前没有创建过,所以这里是False
    if (create_devices) {
   
   
        if (!(*fsm)->DoCreateDevices()) return false;
    }
	
	// -----------------------------第二部分-----------------------------
    return (*fsm)->DoFirstStageMount();
}

可以看到DoFirstStageMount的做了两件事,分别为:

  • 调用FirstStageMount类的Create方法,返回一个参数fsm【大概率跟FirstStageMount有关,因为第二部分调用了它的DoFirstStageMount方法】
  • 第二部分,调用FirstStageMount类的DoFirstStageMount方法

本文先讲解第一部分Create方法

3.FirstStageMount::Create()

// 路径:/system/core/init/first_stage_mount.cpp
Result<std::unique_ptr<FirstStageMount>> FirstStageMount::Create() {
   
   
	// 读取第一阶段的Fstab文件
    auto fstab = ReadFirstStageFstab();
    if (!fstab.ok()) {
   
   
        return fstab.error();
    }
	// AVB2应该返回一个由fstab转译的独占指针【这里也说名了第二部分的fsm指针是啥】
    if (IsDtVbmetaCompatible(*fstab)) {
   
   
        return std::make_unique<FirstStageMountVBootV2>(std::move(*fstab));
    } else {
   
   
        return std::make_unique<FirstStageMountVBootV1>(std::move(*fstab));
    }
}

3.1 ReadFirstStageFstab

// 路径: /system/core/init/first_stage_mount.cpp
static Result<Fstab> ReadFirstStageFstab() {
   
   
    Fstab fstab;
    if (!ReadFstabFromDt(&fstab)) {
   
   
        if (ReadDefaultFstab(&fstab)) {
   
   
            fstab.erase(std::remove_if(fstab.begin(), fstab.end(),
                                       [](const auto& entry) {
   
   
                                           return !entry.fs_mgr_flags.first_stage_mount;
                                       }),
                        fstab.end());
        } else {
   
   
            return Error() << "failed to read default fstab for first stage mount";
        }
    }
    return fstab;
}

从函数的字面意思,我们大致推断:

  • 先从设备树文件中读取Fstab文件【ReadFstabFromDt】
    • 如果失败了, 就去读取默认的Fstab文件;并且删除其中 fs_mgr_flags中没有first_stage_mount不为1的,也就是这个参数没有设置

3.2 ReadFstabFromDt

// 路径: /system/core/fs_mgr/fs_mgr_fstab.cpp
bool ReadDefaultFstab(Fstab* fstab) {
   
   
    fstab->clear();
    // 调用ReadFstabFromDt(fstab, false)重载函数
    ReadFstabFromDt(fstab, false /* verbose */);

    std::string default_fstab_path;
    // Use different fstab paths for normal boot and recovery boot, respectively
    if (access("/system/bin/recovery", F_OK) == 0) {
   
   
        default_fstab_path = "/etc/recovery.fstab";
    
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值