上一篇请参考<Android init介绍(上)>
5. AIL
在init启动过程中,系统服务等均是通过解析rc文件来启动,而rc文件则是由Android初始化语言(Android Init Language)的脚本写成
5.1 格式介绍
AIL以Section为区分,由如下import、action和service三类Section
5.1.1 import section
主要用于导入其他rc文件
import <path>
上面的命令将导入/init.environ.rc然后被解析为action和service
5.1.2 action section
action section由trigger和一些command组成
以on开头,trigger是判断条件,command是具体执行一些操作;当满足trigger条件时,执行这些command
格式如下
on <trigger> [&& <trigger>]* <command> <command> <command>
trigger的内容包含如下
/* * 字事件 * -- 表示当trigger early或QueueEventTrigger("early")调用时触发 */ on early /* * 属性 * -- 表示当sys.boot_from_charger_mode的值通过property_set设置为1时触发 */ on property:sys.boot_from_charger_mode=1 /* * 多个条件用&&连接 * -- 表示当zygote-start触发并且ro.crypto.state属性值为unencrypted时触发 on zygote-start && property:ro.crypto.state=unencrypted
command就是一些具体的操作,由BuiltinFunctionMap::Map(builtin_functions)定义来执行特定的操作
// 终止charger服务 class_stop charger // 开启watchdogd服务 start watchdogd // 触发late-init trigger late-init
5.1.3 service section
service section由service加上一些option组成
以service开头,name是为服务名称,pathname为服务的执行文件路径,argument表示执行文件带的参数,option表示这个服务的一些配置,option由
OptionParserMap::Map(
option_parsers
)
定义
service <name> <pathname> [ <argument> ]*
<option>
<option>
...
5.2 文件解析
/* * 初始化Subcontext */ InitializeSubcontexts() SelinuxHasVendorInit() Subcontext::Subcontext() Subcontext::Fork() fork() execv("/init", {"/init", "subcontext", "u:r:vendor_init:s0", fd, nullptr}) // 创建ActionManager实例 ActionManager::GetInstance() // 创建ServiceList实例 ServiceList::GetInstance() LoadBootScripts() CreateParser(ActionManager, ServiceList) Parser::ParseConfig("/init.rc") Parser::ParseConfig("/system/etc/init") Parser::ParseConfig("/vendor/etc/init") Parser::ParseConfigFile() Parser::ParseData()
5.3 事件触发
/* * am为ActionManager::GetInstance() * QueueEventTrigger构造了一个EventTrigger对象, 放到事件队列中 * !!!注意此处并没有触发 */ am.QueueEventTrigger("early-init"); am.QueueEventTrigger("init"); am.QueueEventTrigger("late-init"); /* * QueueBuiltinAction构造了一个Action对象, 放到事件队列和动作队列中 * !!!注意此处并没有触发 */ am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done"); am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng"); am.QueueBuiltinAction(SetMmapRndBitsAction, "SetMmapRndBits"); am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict"); am.QueueBuiltinAction(keychord_init_action, "keychord_init"); am.QueueBuiltinAction(console_init_action, "console_init"); am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng"); am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers"); while (true) { ... if (!(waiting_for_prop || Service::is_exec_service_running())) { // 依次触发early-init、init、late-init的命令 am.ExecuteOneCommand(); } ... }
参考:
<Android系统启动流程>
<Android 9.0 init进程分析>
<Android 8.1 启动篇(一) -- 深入研究 init>
<https://zhuanlan.zhihu.com/p/83123906>