system\core\init\init.cpp----LoadBootScripts()解析init.rc(2)

这段代码是安卓系统启动时用于加载和解析初始化脚本(rc文件)的核心函数,主要功能是根据系统属性或默认路径加载配置文件,构建服务(Service)和动作(Action)的管理结构。以下是逐行详细解析:

​函数功能概述​

  • • ​​输入参数​​:

    • ActionManager& action_manager:管理动作(如启动服务、执行命令)的对象。

    • ServiceList& service_list:管理所有服务(如zygote、servicemanager)的对象。

  • • ​​核心逻辑​​:

      1. ​创建解析器​ ​:通过CreateParser生成一个Parser对象,用于解析rc文件。
      1. ​获取启动脚本路径​ ​:通过系统属性ro.boot.init_rc获取用户指定的初始化脚本路径,若未指定则使用默认路径。
      1. ​解析配置文件​​:
      • • 若ro.boot.init_rc为空,按固定顺序解析默认路径下的rc文件(如/system/etc/init/hw/init.rc)。

      • • 若指定路径,则直接解析该路径的文件。

      1. ​处理导入路径​ ​:若某级目录解析失败,将其加入late_import_paths,后续可能延迟加载(仅适用于Android Q及之前版本)。

​关键代码解析​

​1. 创建解析器​
复制代码
复制代码

Parser parser = CreateParser(action_manager, service_list);

  • • ​​作用​ ​:初始化一个Parser对象,绑定ActionManagerServiceList,用于后续解析rc文件中的serviceon(动作)和import(导入其他rc文件)指令

  • • ​​解析器组成​​:

    • ServiceParser:解析service关键字,创建服务对象并注册到service_list

    • ActionParser:解析on关键字,创建动作对象并注册到action_manager

    • ImportParser:解析import关键字,递归加载其他rc文件

​2. 获取启动脚本路径​
复制代码
复制代码

std::string bootscript = GetProperty("ro.boot.init_rc", "");

  • • ​​作用​ ​:通过系统属性ro.boot.init_rc获取用户指定的初始化脚本路径(如通过init命令行参数androidboot.init_rc=/path/to/init.rc设置)。

  • • ​​默认情况​​:若属性为空,则使用系统默认的rc文件路径

​3. 解析默认路径的rc文件​
复制代码
复制代码

if (bootscript.empty()) { parser.ParseConfig("/system/etc/init/hw/init.rc"); // 优先解析硬件适配的init.rc if (!parser.ParseConfig("/system/etc/init")) { // 解析/system/etc/init目录 late_import_paths.emplace_back("/system/etc/init"); // 记录失败路径,后续延迟加载 } // 跳过/system_ext(Android Q及之前无此分区) parser.ParseConfig("/vendor/etc/init"); // 解析vendor分区rc if (!parser.ParseConfig("/odm/etc/init")) { // 解析ODM分区rc late_import_paths.emplace_back("/odm/etc/init"); } parser.ParseConfig("/product/etc/init"); // 解析product分区rc if (!parser.ParseConfig("/product/etc/init")) { // 解析product分区rc(重复检查,可能冗余) late_import_paths.emplace_back("/product/etc/init"); } }

  • • ​​路径解析顺序​​:

      1. ​硬件适配配置​ ​:/system/etc/init/hw/init.rc,优先加载与设备硬件相关的初始化脚本

      1. ​系统通用配置​ ​:/system/etc/init,包含系统级服务定义(如zygote启动配置)

      1. ​厂商定制配置​ ​:/vendor/etc/init/odm/etc/init,由设备厂商或ODM添加的自定义服务

  • • ​​错误处理​ ​:若某级目录解析失败(如文件不存在),将其路径加入late_import_paths,后续可能通过其他机制延迟加载

​4. 解析用户指定的启动脚本​
复制代码
复制代码

else { parser.ParseConfig(bootscript); }

  • • ​​作用​ ​:若ro.boot.init_rc指定了自定义路径(如测试环境或特殊设备),直接解析该路径的rc文件,覆盖默认配置

​核心数据结构与机制​

    1. Parser类​​:
    • • 负责解析rc文件,通过AddSectionParser注册不同类型的解析器(如ServiceParserActionParser),根据文件中的关键字(如serviceon)调用对应的解析逻辑

    • ParseConfig方法:解析单个文件或目录(目录下所有文件按字母顺序解析)

    1. late_import_paths​:
    • • 用于记录解析失败的路径,后续可能通过其他机制(如late-init阶段)延迟加载

    • • ​​注意​ ​:Android Q及之前版本支持late_import,但Android R及之后已移除该机制

​典型应用场景​

  • • ​​系统启动阶段​​:

    init进程的SecondStageMain中调用此函数,加载并解析init.rc及其相关配置文件,构建服务树和动作队列,为启动Zygote和SystemServer做准备

  • • ​​定制化需求​​:

    厂商或开发者可通过修改ro.boot.init_rc属性,指定自定义的初始化脚本路径,覆盖系统默认行为

​总结​

这段代码是安卓系统初始化的核心逻辑之一,通过解析rc文件定义服务、动作和依赖关系,驱动系统从启动到进入用户界面的全过程。其设计灵活,支持硬件适配、厂商定制和动态加载,是理解安卓启动流程的关键环节。