Android 系统中 Init 进程解析 init.rc 文件的完整流程,揭示系统服务启动的核心机制:
一、解析准备:构建解析器与加载配置文件
在 Init 进程的第二阶段(SecondStageMain),系统会创建专门的解析器来处理 init.rc 配置。
1. 创建解析器(Parser)
-
作用:将文本格式的
init.rc转换为可执行的内部对象(Action和Service)。 -
核心组件:
ServiceParser:解析service块,生成Service对象(记录服务名、路径、权限等)。ActionParser:解析on块,生成Action对象(记录触发条件和执行命令)。ImportParser:处理import命令,动态加载其他.rc文件(如init.zygote.rc)。
2. 加载 rc 文件的顺序
系统按以下优先级加载配置文件(前一个文件的配置会被后一个覆盖):
-
/init.rc:核心配置,定义系统最基础的服务和动作(如servicemanager、zygote)。 -
/system/etc/init/:系统分区的扩展配置(如硬件相关服务)。 -
/product/etc/init/:厂商定制分区的配置(如特定型号设备的服务)。 -
/vendor/etc/init/:供应商分区的配置(如高通、联发科的私有服务)。
- 动态加载:若内核参数指定
androidboot.init_rc=xxx,则优先加载指定文件。
二、解析过程:从文本到对象的转换
1. 解析 service 块:生成 Service 对象
示例配置:
ini
service zygote /system/bin/app_process64 -Xzygote --zygote --start-system-server
class core
user root
group root readproc
socket zygote stream 660 root system
解析结果:
-
Service对象属性:name_ = "zygote"classnames_ = {"core"}(属于core服务类别)user_ = "root",group_ = "root readproc"(运行权限)socket_ = "/dev/socket/zygote"(通信套接字)
2. 解析 on 块:生成 Action 对象
示例配置:
ini
on boot
class_start core # 启动所有 core 类服务
setprop sys.boot_completed 1 # 设置系统属性
解析结果:
-
Action对象属性:event_trigger_ = "boot"(触发条件为系统启动)commands_包含两个命令:class_start core和setprop sys.boot_completed 1
三、执行逻辑:事件触发与命令调度
1. 事件队列与动作执行
-
事件类型:
- 系统事件:如
early-init(初始化早期)、init(初始化完成)、boot(系统启动完成)。 - 属性事件:如
on property:sys.boot_completed=1(属性值变化时触发)。
- 系统事件:如
-
执行流程:
- 入队事件:通过
am.QueueEventTrigger("init")将事件加入队列。 - 匹配动作:
ActionManager遍历所有Action,找到触发条件匹配的Action(如on init对应的Action)。 - 执行命令:按顺序执行
Action中的每个命令(如先执行sysclktz 0,再执行symlink /system/etc /etc)。
- 入队事件:通过
2. 服务启动策略
- 按类别启动:通过
class_start core批量启动同一类别(如core)的所有服务。 - 延迟启动:标记为
disabled的服务(如adbd)需手动通过start adbd启动。 - 崩溃重启:未标记
oneshot的服务崩溃后自动重启;标记critical的服务若频繁崩溃(如 4 次 / 4 分钟),系统重启到 Bootloader。
四、关键数据结构与内存管理
1. ActionManager:管理动作执行
-
核心成员:
actions_:存储所有解析出的Action对象。event_queue_:待处理的事件队列(如early-init、boot)。
-
执行优化:
- 每次调用
ExecuteOneCommand()仅执行一个命令,避免长命令阻塞启动流程。 - 超过 50ms 的命令会被记录警告,便于性能调优。
- 每次调用
2. ServiceList:管理服务生命周期
-
核心成员:
services_:存储所有解析出的Service对象。delayed_service_names_:延迟启动的服务列表(如依赖其他服务的服务)。
-
状态监控:
- 记录服务的启动时间、崩溃次数、CPU 优先级(
oom_score_adj)等,用于资源调度和故障恢复。
- 记录服务的启动时间、崩溃次数、CPU 优先级(
五、典型启动流程示例
以 zygote 服务为例,看其从配置到启动的完整路径:
-
解析阶段:
init.rc中的service zygote ...被解析为Service对象,加入ServiceList。
-
事件触发:
- 当
ActionManager处理boot事件时,执行class_start core命令,触发zygote启动。
- 当
-
执行启动:
- Init 进程通过
fork()创建zygote子进程,子进程加载 Java 运行时(ART)并监听应用启动请求。
- Init 进程通过
六、总结:init.rc 如何驱动系统启动
init.rc 是 Android 系统启动的「剧本」,通过 解析 - 调度 - 执行 三部曲实现:
-
解析:将文本配置转换为
Action和Service对象,建立系统服务的元数据模型。 -
调度:通过事件队列(
event_queue_)和动作管理器(ActionManager)按顺序触发初始化操作。 -
执行:启动服务、设置属性、挂载分区等具体操作,最终完成从内核到用户空间的过渡。
理解这一流程,不仅能深入掌握 Android 启动机制,还能在定制系统时精准修改服务配置(如添加自定义服务、调整启动顺序),是系统开发与调试的核心基础。