在解析Init.rc之前需要对init.rc文件有一个认识,init.rc是由一种被称为"Android初始化语言"(Android Init Language,这里简称为AIL)的脚本写成的文件.该语言是由语句组成的,主要包含了五种类型的语句:
- Action
- Commands
- Services
- Options
- Import
在init.rc文件中一条语句通常占用一行,单词之间是用空格符来相隔的。如果一行写不下,可以在行尾加上反斜杠,来连接下一行。也就是说,可以用反斜杠将多行代码连接成一行代码。并且使用#来进行注释。在init.rc中分成三个部分(Section),而每一部分的开头需要指定on(Actions)、service(Services)或import。也就是说,每一个Actions, import或 Services确定一个Section。而所有的Commands和Options只能属于最近定义的Section。如果Commands和 Options在第一个Section之前被定义,它们将被忽略。Actions和Services的名称必须唯一。如果有两个或多个Actions或Services拥有同样的名称,那么init在执行它们时将抛出错误,并忽略这些Action和Service。
我们在之前分析init进程时讲到过在init.cpp的main函数中将service, on, import设置为三个Section.
Parser& parser = Parser::GetInstance();
parser.AddSectionParser("service",std::make_unique<ServiceParser>());
parser.AddSectionParser("on", std::make_unique<ActionParser>());
parser.AddSectionParser("import", std::make_unique<ImportParser>());
下面来看一下Action,Service,Import都是该怎么定义的.
在system/core/init/readme.txt中详细说明
Action的格式如下:
on <trigger> [&& <trigger>]* //设置触发器
<command>
<command> //动作触发之后要执行的命令
<command>
Triggers //对trigger的详细讲解
--------
Triggers are strings which can be used to match certain kinds of
events and used to cause an action to occur.
Triggers are subdivided into event triggers and property triggers.
Event triggers are strings triggered by the 'trigger' command or by
the QueueEventTrigger() function within the init executable. These
take the form of a simple string such as 'boot' or 'late-init'.
Property triggers are strings triggered when a named property changes
value to a given new value or when a named property changes value to
any new value. These take the form of 'property:<name>=<value>' and
'property:<name>=*' respectively. Property triggers are additionally
evaluated and triggered accordingly during the initial boot phase of
init.
An Action can have multiple property triggers but may only have one
event trigger.
For example:
'on boot && property:a=b' defines an action that is only executed when
the 'boot' event trigger happens and the property a equals b.
'on property:a=b && property:c=d' defines an action that is executed
at three times,
1) During initial boot if property a=b and property c=d
2) Any time that property a transitions to value b, while property
c already equals d.
3) Any time that property c transitions to value d, while property
a already equals b.
在init.cpp中设置的trigger有early-init, init, late-init等, 当trigger被触发时就执行command,
我们来看一个标准的Action:
on early-init //trigger为early-init,在init.cpp的main函数中设置过
# Set init and its forked children's oom_adj.
write /proc/1/oom_score_adj -1000 //调用do_write函数, 写入oom_score_adj为-1000
# Disable sysrq from keyboard
write /proc/sys/kernel/sysrq 0
# Set the security context of /adb_keys if present.
restorecon /adb_keys //为adb_keys 重置安全上下文
# Shouldn't be necessary, but sdcard won't start without it. http://b/22568628.
mkdir /mnt 0775 root system //创建mnt目录
# Set the security context of /postinstall if present.
restorecon /postinstall
start ueventd //调用函数do_start, 启动服务uevent,
下面对所有命令详细讲解.
bootchart_init //初始化bootchart,用于获取开机过程系统信息
Start bootcharting if configured (see below).
This is included in the default init.rc.
chmod <octal-mode> <path> //改变文件的权限
Change file access permissions.
chown <owner> <group> <path> //改变文件的群组
Change file owner and group.
class_start <serviceclass> //启动所有具有特定class的services
Start all services of the specified class if they are
not already running.
class_stop <serviceclass> //将具有特定class的所有运行中的services给停止或者diasble
Stop and disable all services of the specified class if they are
currently running.
class_reset <serviceclass> //先将services stop掉, 之后可能会通过class_start再重新启动起来
Stop all services of the specified class if they are
currently running, without disabling them. They can be restarted
later using class_start.
copy <src> <dst> //复制文件
Copies a file. Similar to write, but useful for binary/large
amounts of data.
domainname <name>
Set the domain name.
enable <servicename> //如果services没有特定disable,就将他设为enable
Turns a disabled service into an enabled one as if the service did not
specify disabled.
If the service is supposed to be running, it will be started now.
Typically used when the bootloader sets a variable that indicates a specific
service should be started when needed. E.g.
on property:ro.boot.myfancyhardware=1
enable my_fancy_service_for_my_fancy_hardware
exec [ <seclabel> [ <user> [ <group> ]* ] ] -- <command> [ <argument> ]* //创建执行程序.比较重要,后面启动service要用到
Fork and execute command with the given arguments. The command starts
after "--" so that an optional security context, user, and supplementary
groups can be provided. No other commands will be run until this one
export <name> <value> //在全局设置环境变量
Set the environment variable <name> equal to <value> in the
global environ