init.rc简介
init.rc文件由系统第一个启动的init程序进行解析.它由”Android Init Language”语言编写而成.init.rc文件可以在你android设备根目录下找到.还记得我们上次编译的Android源码么?如果你已经编译过源码了,那么可以在out/target/generic/root/目录下找到该文件.
要想读懂init.rc文件,首先要掌握Android Init Language语言,即AIL.在/system/core/init/下有一份readme.txt文件,为我们详细介绍了有关AIL的知识.我们下面的学习同样是借助了该文档来的.
AIL语法
AIL语言非常简单,主要包括两部分:结构语法及注释语法.下面我们就这两点进行说明
结构语法
AIL语言包含主要包含五种结构语法:
- Actions
- Services
- Options
- Commands
- Imports
需要注意,AIL采用是面向行的代码风格,即用换行符作为一条语句的分隔符,也就是在init.rc中以一条语句通常占据一行.如果一行写不下,可以在行尾添加反斜杠来链接到下一行,换言之,通过行尾添加反斜杠符可以将多行代码链接为一行代码.
init.rc有许多Service和Action组成.那么什么是Service和Action呢?
Action和Service显式声明了一个语句块,而Commands和Options则分别用来定义Actions和Service(你可以理解为这是Action或者Service的属性).
另外,我们声明的Commands和Options属于最近声明的语句块,即就近原则.需要注意,在第一个语句块之前的commands和options会被忽略.
每个Actions或者Services应该有唯一的名字.对于名字重复的情况,Action和Service有自己不同的处理方式:
如果第二个定义的Action的名字和之前存在Action的名字相同,第二个Action中定义的Commands将会被添加到已经存在的同名Action中.如果第二个定义的Service的名字和之前存在的Service的名字相同,第二个Service会被忽略并输出错误信息.
注释语法
AIL中的注释语法和Shell脚本一致,以#开头即可
结构语法详解
Actions
Actions代表一些Action.Action代表一组命令,它包含一个触发器,该触发器决定了何时执行这个Action,即在什么情况下才能执行该Action中的定义命令.当一些条件满足触发器的条件时,该Action中定义的命令会被添加到要执行命令队列的尾部(如果这组命令已经在队列中,则不会再次添加).
当一个Action从队列移除时,该Action定义的命令会依次被执行.
Action的格式如下:
on <trgger> [&& <trigger>]*
<command>
<command>
<command>
...
不难发现Action都是以on开始,随后会定义触发器(trigger),接着便是为其定义命令(Commmand).在开始讲解Trigger和Command之前,我们先来看一段Action的示例代码:
on boot
# 初始化网络
ifup lo
hostname localhost
domainname localdomain
trigger
trigger即我们上面所说的触发器,本质上是一个字符串,能够匹配某种包含该字符串的事件.
trigger又被细分为事件触发器(event trigger)和属性触发器(property trigger).
事件触发器可由”trigger”命令或初始化过程中通过QueueEventTrigger()触发,通常是一些事先定义的简单字符串,例如:boot
,late-init
属性触发器是当指定属性的变量值变成指定值时触发,其格式为property:<name>=*
一个Action可以有多个属性触发器,但是最多有一个事件触发器.下面我们看两个例子:
on boot && property:a=b
该Action只有在boot事件发生时,并且属性a和b相等的情况下才会被触发.