最近在分析安卓的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的,也就是这个参数没有设置
- 如果失败了, 就去读取默认的Fstab文件;并且删除其中
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";

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

被折叠的 条评论
为什么被折叠?



