安卓启动流程(一) - rc文件初步解析

2021-08-25  本文已影响0人  七零八落问号

init进程的一个核心部分,是通过解析rc文件,执行Action和启动Service。在分析init进程前,有必要先学习rc文件的配置和解析的原理。

初始化rc文件解析相关工具

/system/core/init/init.cpp

int main(int argc, char** argv) {
    ...
    // 设置Action内建函数跳转表
    const BuiltinFunctionMap function_map;
    Action::set_function_map(&function_map);

    // 创建供应商子进程
    subcontexts = InitializeSubcontexts();

    // ActionManager实例, 维护rc文件解析的Action数据
    ActionManager& am = ActionManager::GetInstance();
    // ServiceList实例, 维护rc文件解析的Service数据
    ServiceList& sm = ServiceList::GetInstance();
  
    // 开始解析RC文件
    LoadBootScripts(am, sm);
    ...
}

解析RC文件

/system/core/init/init.cpp

static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
    Parser parser = CreateParser(action_manager, service_list);

    std::string bootscript = GetProperty("ro.boot.init_rc", "");
    if (bootscript.empty()) {
        parser.ParseConfig("/init.rc");
        if (!parser.ParseConfig("/system/etc/init")) {
            late_import_paths.emplace_back("/system/etc/init");
        }
        if (!parser.ParseConfig("/product/etc/init")) {
            late_import_paths.emplace_back("/product/etc/init");
        }
        if (!parser.ParseConfig("/odm/etc/init")) {
            late_import_paths.emplace_back("/odm/etc/init");
        }
        if (!parser.ParseConfig("/vendor/etc/init")) {
            late_import_paths.emplace_back("/vendor/etc/init");
        }
    } else {
        parser.ParseConfig(bootscript);
    }
}

Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) {
    Parser parser;
    parser.AddSectionParser("service", std::make_unique<ServiceParser>(&service_list, subcontexts));
    parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager, subcontexts));
    parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));
    return parser;
}

通过CreateParser, 创建了Parser解析器对象,其解析规则如下:

匹配项 解析器 示例
service ServiceParser service ueventd /sbin/ueventd
on ActionParser on early-init
import ImportParser import /init.${ro.zygote}.rc

然后开始执行解析过程

最后调用Parser解析器的ParseConfig函数执行解析。


下一篇:安卓启动流程(二) - Parser解析器

上一篇下一篇

猜你喜欢

热点阅读