Android init介绍(下)

上一篇请参考<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表示这个服务的一些配置,optionOptionParserMap::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>

Android init介绍(下)

上一篇:手机数据通过无线局域网同步到笔记本硬盘的解决方案


下一篇:《移动WEB前端高级开发实践@www.java1234.com》——3