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