![64bd66f6512f3ecc789b7f75c524f243.png](https://i-blog.csdnimg.cn/blog_migrate/28f0360908c83b9439dbf76c2c1201a2.jpeg)
1 概述
Android Init Language,简称AIL,即安卓初始化语言。Android init进程解析的扩展名为rc文件就是用这种语言写的。
所有语法规则都可以在readme.txt文件中获取。本文基于Android N的readme文件进行讲解,基本是对此文件的翻译,感觉翻译不到位的,可以查看原英文文件,路径如下:
android/system/core/init/readme.txt
2 语法
安卓初始化语言由五大类语句组成,分别是Actions、Commands、Services、Options和Imports。
所有这些都是以行为单位,各种记号由空格来隔开。C语言风格的反斜杠号可用于在记号间插入空格。双引号也可用于防止字符串被空格分割成多个记号。行末的反斜杠用于折行。
注释行以井号(#)开头(允许以空格开头)。
Actions和Services声明一个新的分组。所有的命令或选项都属于最近申明的分组。位于第一个分组之前的命令或选项将会被忽略。 Actions和Services有唯一的名字。如果Action出现重名,第二个Action的commands将被加在第一个的后面。如果Services出现重名,第二个将被忽略,并且会打印一条错误日志。
2.1 Actions
Actions其实就是一序列的Commands(命令)。Actions都有一个trigger(触发器),它被用于决定action的执行时间。当一个符合action触发条件的事件发生时,action会被加入到执行队列的末尾,除非它已经在队列里了。
队列中的每一个action都被依次提取出,而这个action中的每个command(命令)都将被依次执行。Init在这些命令的执行期间还控制着其他的活动(设备节点的创建和注销、属性的设置、进程的重启)。
Actions格式如下:
![827d300c1e5d7f4f7329e5c0f2c19367.png](https://i-blog.csdnimg.cn/blog_migrate/d5bfd8e6f56153d3d5b73ebb1c4432cc.jpeg)
2.2 Triggers
触发器本质上是一个字符串,能够匹配某种包含该字符串的事件。触发器又被细分为事件触发器(event trigger)和属性触发器(property trigger)。触发器是一个用于匹配特定事件类型的字符串,用于是Actions发生。
事件触发器可由"trigger"命令触发,或初始化过程中通过QueueEventTrigger()触发,通常是一些事先定义的简单字符串,例如:boot,late-init。
属性触发器是当指定属性的变量值变成指定值时触发,其格式为'property:=' and 'property:=*'。
一个Action可以有多个属性触发器,但是最多有一个事件触发器.
下面我们看两个例子:
on boot && property:a=b
该Action只有在boot事件发生时,并且属性a和b相等的情况下才会被触发.
on property:a=b && property:c=d
该Action会在以下三种情况被触发:
1)在启动时,如果属性a的值等于b并且属性c的值等于d
2)在属性c的值已经是d的情况下,属性a的值被更新为b
3)在属性a的值已经是b的情况下,属性c的值被更新为d
触发器分为定义好的触发器和设置的触发器。
2.2.1 定义好的触发器
定义好的事件触发器有early-initinitlate-init,是在初始化过程中通过QueueEventTrigger()触发。
early-init
一些前置工作,创建mnt目录,挂载tmpfs等。
init
设置loglevel,建立符号链接,创建system/data/cache目录,proc/dev处理等。
late-init
触发用户设置的触发器。
2.2.2 创建的触发器
用户创建的触发器,通过2.2.1中某一个阶段的trigger命令触发。
trigger
触发某一触发器。
2.3 Commands
command有很多,请查阅readme.txt文件。
2.4 Services
Init启动的程序,可以选择要不要在退出后重启。格式如下:
![a45867b692e4751ddf3dd332c3c3e6a2.png](https://i-blog.csdnimg.cn/blog_migrate/221978f133c0ed5cc37dd02c240ef3cd.jpeg)
2.5 Options
Options是服务的修饰符,他们影响Init运行服务的方式和时间。
Critical
这是一项设备关键型服务。 如果它在四分钟内退出超过四次以上,设备将重启进入恢复模式。
Class
指定服务的类名。 命名类中的所有服务可以一起启动或停止。 如果未通过class选项指定服务,则服务在类"default"中。
Seclabel
在执行此服务之前更改为"seclabel"。 主要供从rootfs运行的服务使用,例如 ueventd,adbd。 系统分区上的服务可以基于其文件安全上下文使用策略定义的转换。
如果未指定且策略中未定义转换,则默认为init上下文。
group [ ]*
在执行此服务之前更改为groupname。 除了(必需的)第一个之外的其他组名用于设置过程的补充组(通过setgroups())。 目前默认为root。
User
在执行此服务前更改为username。
Oneshot
服务退出后,不进行重启。
onrestart
当服务重启的时候,执行一条指令。
Disabled
此服务不会自动从其类开始。 它必须通过名称显式启动。
socket [ [ [ ] ] ]
创建名为/ dev / socket / 的unix域套接字,并将其fd传递给已启动的进程。 必须是"dgram","stream"或"seqpacket"。 用户和组默认为0.'seclabel'是套接字的SELinux安全上下文。 它默认为服务安全性上下文,由seclabel指定或基于服务可执行文件安全性上下文计算。
setenv
在启动的进程中将环境变量设置为。
ioprio <0-7>
设置IO优先级。
writepid
当进程创建的时候,把进程ID写到给定的文件里面。意味着cgroup / cpuset的使用。
2.6 Imports
import关键字不是一个命令,而是一个部分,并在包含它的.rc文件完成解析后立即处理。
import
解析init配置文件,扩展当前配置。 如果是目录,则目录中的每个文件都将被解析为配置文件。 它不是递归的,嵌套目录不会被解析。
init可以执行imports的rc文件只有两次:
1)在初始引导期间导入/init.rc时
2)在mount_all期间在指定路径导入/ {system,vendor,odm} / etc / init /或.rc文件时
2.7 Properties
Init通过以下属性提供有关其负责的服务的信息。
init.svc.
命名服务的状态("stopped