system\core\init\init.cpp----LoadBootScripts()解析init.rc(2)
这段代码是安卓系统启动时用于加载和解析初始化脚本(rc文件)的核心函数,主要功能是根据系统属性或默认路径加载配置文件,构建服务(Service)和动作(Action)的管理结构。以下是逐行详细解析:
函数功能概述
- •
输入参数:
- •
ActionManager& action_manager
:管理动作(如启动服务、执行命令)的对象。 - •
ServiceList& service_list
:管理所有服务(如zygote、servicemanager)的对象。
- •
- •
核心逻辑:
- 1.
创建解析器:通过
CreateParser
生成一个Parser
对象,用于解析rc文件。 - 2.
获取启动脚本路径:通过系统属性
ro.boot.init_rc
获取用户指定的初始化脚本路径,若未指定则使用默认路径。 - 3.
解析配置文件:
- •
若
ro.boot.init_rc
为空,按固定顺序解析默认路径下的rc文件(如/system/etc/init/hw/init.rc
)。 - •
若指定路径,则直接解析该路径的文件。
- •
- 4.
处理导入路径:若某级目录解析失败,将其加入
late_import_paths
,后续可能延迟加载(仅适用于Android Q及之前版本)。
- 1.
关键代码解析
1. 创建解析器
Parser parser = CreateParser(action_manager, service_list);
- •
作用:初始化一个
。Parser
对象,绑定ActionManager
和ServiceList
,用于后续解析rc文件中的service
、on
(动作)和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
,优先加载与设备硬件相关的初始化脚本 - 2.
系统通用配置:
。/system/etc/init
,包含系统级服务定义(如zygote启动配置) - 3.
厂商定制配置:
。/vendor/etc/init
、/odm/etc/init
,由设备厂商或ODM添加的自定义服务
- 1.
- •
错误处理:若某级目录解析失败(如文件不存在),将其路径加入
。late_import_paths
,后续可能通过其他机制延迟加载
4. 解析用户指定的启动脚本
else { parser.ParseConfig(bootscript); }
- •
作用:若
。ro.boot.init_rc
指定了自定义路径(如测试环境或特殊设备),直接解析该路径的rc文件,覆盖默认配置
核心数据结构与机制
- 1.
Parser
类:- •
负责解析rc文件,通过
。AddSectionParser
注册不同类型的解析器(如ServiceParser
、ActionParser
),根据文件中的关键字(如service
、on
)调用对应的解析逻辑 - •
。ParseConfig
方法:解析单个文件或目录(目录下所有文件按字母顺序解析)
- •
- 2.
late_import_paths
:- •
用于记录解析失败的路径,后续可能通过其他机制(如
。late-init
阶段)延迟加载 - •
注意:Android Q及之前版本支持
。late_import
,但Android R及之后已移除该机制
- •
典型应用场景
- •
系统启动阶段:
在
。init
进程的SecondStageMain
中调用此函数,加载并解析init.rc
及其相关配置文件,构建服务树和动作队列,为启动Zygote和SystemServer做准备 - •
定制化需求:
厂商或开发者可通过修改
。ro.boot.init_rc
属性,指定自定义的初始化脚本路径,覆盖系统默认行为
总结
这段代码是安卓系统初始化的核心逻辑之一,通过解析rc文件定义服务、动作和依赖关系,驱动系统从启动到进入用户界面的全过程。其设计灵活,支持硬件适配、厂商定制和动态加载,是理解安卓启动流程的关键环节。