Android系统10 RK3399 init进程启动(四十二) init.rc文件解析逻辑

配套系列教学视频链接:

      安卓系列教程之ROM系统开发-百问100ask

说明

系统:Android10.0

设备: FireFly RK3399 (ROC-RK3399-PC-PLUS)

前言

Android init启动的时候会解析init.rc, 当然还有很多其他rc文件, 在init进程代码中有对应的解析器, 本章节重点介绍init.rc中所有的内容是如何被解析的,理解这个解析逻辑, 有利于你对rc文件中action和service实际的执行逻辑,方便后期根据需求做一些深度定制化。


一, 整体解析逻辑框图

整个解析过程都是面向对象, 有解析器Parser, Action,Command, ActionManger, Service对象, Option对象, ServiceList对象。

二, 解析逻辑

Init在解析RC文件的时候会有如下逻辑:

  1. 解析以section为单位, section包括import, action, service语句。
  2. 不同的section有不同的parser解析器,都继承自SectionParser, 每个parser从上往下解析, 有分析开始(ParseSection), 每一行分析(ParseLineSection), 以及结束分析(EndSection/EndFile)。
  3. ImportParser分析import段落, 将所有的需要导入的文件名拿到, 然后一个一个的分析里面的其他语句。
  4. ActionParser分析action段落, 每个action段落会构建一个Action对象, 每个Action对象包含了所有的命令对象Command, 由ActionManager负责管理和调度所有Action对象。
  5. ServiceParsere分析service段落, 每个service段落会构建一个Service对象, 该对象会记录服务对应的可执行文件路径和参数, 根据不同的option来初始化service对象不同的成员。 最终ServiceList进行管理和调度。

对应代码在system/core/init/init.cpp中



Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) {
    Parser parser;
	// ServiceParser做的事情: 1,首先根据第一行的名字和参数创建出service对象,
	// 2,然后根据选项域的内容填充service对象,
	// 3.最后将创建出的service对象加入到vector类型的service链表(service_list_)中。
    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;
}

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("/product_services/etc/init")) {
            late_import_paths.emplace_back("/product_services/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);
    }
}

代码详细过程,我利用思维导图展开了: 

 所有的解析器都是继承自SectionParser:

class SectionParser {
  public:
    virtual ~SectionParser() {}
    // 一个Section开始需要执行的, 如遇到import, on, service关键词表示开始
    virtual Result<Success> ParseSection(std::vector<std::string>&& args,
                                         const std::string& filename, int line) = 0;
    // 每个section中的每一行, 除了第一行
    virtual Result<Success> ParseLineSection(std::vector<std::string>&&, int) { return Success(); };
    //这两个都表示section解析结束之后需要做的事情, Endfile主要针对import
    virtual Result<Success> EndSection() { return Success(); };
    virtual void EndFile(){};
};

大家感兴趣可以去读一下代码, 读代码只需要去阅读各个SectionParser的以上三个接口,并且按照顺序读就能理解整个逻辑了。

三, 所有Action的执行的先后顺序

启动的过程中,会解析各个Action和Service, 其中Action的执行先后顺序为如下所示:

on SetupCgroups

on early-init

on wait_for_coldboot_done

on MixHwrngIntoLinuxRng

on SetMmapRndBits

on SetKptrRestrict

on KeychordInit

on console_init

on init

on StartBoringSslSelfTest

on MixHwrngIntoLinuxRng

on InitBinder

on queue_property_triggers

on late-init

on early-fs

on fs

on post-fs

on late-fs

on post-fs-data

on zygote-start

on early-boot

on boot

 这也只是一个粗略的先后顺序,给大家一个参考。

四,总结

这部分内容主要是让大家理解逻辑, 方便大家去阅读init进程代码。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旗浩QH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值