AIL(init.rc)
Init.rc是init进程最重要的环节,init.rc文件并不是普通的配置文件,而是由一种被称为“Android初始化语言”(AndroidInitLanguage,这里简称为AIL)的脚本写成的文件。在了解init如何解析init.rc文件之前,先了解AIL非常必要.
AIL由如下4部分组成。
1.动作(Actions)
2.命令(Commands)
3.服务(Services)
4.选项(Options)
这4部分都是面向行的代码,也就是说用回车换行符作为每一条语句的分隔符。如果一行写不下,可以在行尾加上反斜杠,来连接下一行
AIL的注释与很多Shell脚本一行,以#开头。
AIL在编写时需要分成多个部分(Section),而每一部分的开头需要指定Actions或Services。也就是说,每一个Actions或Services确定一个Section。而所有的Commands和Options只能属于最近定义的Section。如果Commands和Options在第一个Section之前被定义,它们将被忽略。
Actions和Services的名称必须唯一。如果有两个或多个Action或Service拥有同样的名称,那么init在执行它们时将抛出错误,并忽略这些Action和Service。
lAction:
也就是说Actions是以关键字on开头的,然后跟一个触发器,接是若干命令。例如,下面就是一个标准的Action
onboot
#basicnetworkinit
ifuplo
hostnamelocalhost
domainnamelocaldomain
其中boot是触发器,下面三行是command
那么init.rc到底支持哪些触发器呢?这个决定于init.c代码如何写的,
Am335x里的init.c触发器如下:
init_parse_config_file("/init.rc");
action_for_each_trigger("early-init",action_add_queue_tail);
queue_builtin_action(wait_for_coldboot_done_action,"wait_for_coldboot_done");
queue_builtin_action(keychord_init_action,"keychord_init");
queue_builtin_action(console_init_action,"console_init");
/*executeallthebootactionstogetusstarted*/
action_for_each_trigger("init",action_add_queue_tail);
/*skipmountingfilesystemsinchargermode*/
if(!is_charger){
action_for_each_trigger("early-fs",action_add_queue_tail);
action_for_each_trigger("fs",action_add_queue_tail);
action_for_each_trigger("post-fs",action_add_queue_tail);
action_for_each_trigger("post-fs-data",action_add_queue_tail);
}
queue_builtin_action(property_service_init_action,"property_service_init");
queue_builtin_action(signal_init_action,"signal_init");
queue_builtin_action(check_startup_action,"check_startup");
if(is_charger){
action_for_each_trigger("charger",action_add_queue_tail);
}else{
action_for_each_trigger("early-boot",action_add_queue_tail);
action_for_each_trigger("boot",action_add_queue_tail);
}
queue_builtin_action(queue_property_triggers_action,"queue_property_triggers");
1.init
这是init执行后第一个被触发Trigger,也就是在/init.rc被装载之后执行该Trigger
2.<name>=<value>
当属性<name>被设置成<value>时被触发。例如,
onproperty:vold.decrypt=trigger_reset_main
class_resetmain
3.device-added-<path>
当设备节点被添加时触发
4.device-removed-<path>
当设备节点被移除时添加
5.service-exited-<name>
会在一个特定的服务退出时触发
lCommands
Actions后需要跟若干个命令,Command就是系统支持的一系列命令,如:export,hostname,mkdir,mount,等等,其中一部分是linux命令,还有一些是android添加的,如:class_start<serviceclass>
这些命令如下:
1.exec<path>[<argument>]*
创建和执行一个程序(<path>)。在程序完全执行前,init将会阻塞。由于它不是内置命令,应尽量避免使用exec,它可能会引起init执行超时。
2.export<name><value>
在全局环境中将<name>变量的值设为<value>。(这将会被所有在这命令之后运行的进程所继承)
3.ifup<interface>
启动网络接口
4.import<filename>
指定要解析的其他配置文件。常被用于当前配置文件的扩展
5.hostname<name>
设置主机名
6.chdir<directory>
改变工作目录
7.chmod<octal-mode><path>
改变文件的访问权限
8.chown<owner><group><path>
更改文件的所有者和组
9.chroot<directory>
改变处理根目录
10.class_start<serviceclass>
启动所有指定服务类下的未运行服务。
11class_stop<serviceclass>
停止指定服务类下的所有已运行的服务。
12.domainname<name>
设置域名
13.insmod<path>
加载<path>指定的驱动模块
14.mkdir<path>[mode][owner][group]
创建一个目录<path>,可以选择性地指定mode、owner以及group。如果没有指定,默认的权限为755,并属于root用户和root组。
15.mount<type><device><dir>[<mountoption>]*
试图在目录<dir>挂载指定的设备。<device>可以是mtd@name的形式指定一个mtd块设备。<mountoption>包括"ro"、"rw"、"re
16.setkey
保留,暂时未用
17.setprop<name><value>
将系统属性<name>的值设为<value>。
18.setrlimit<resource><cur><max>
设置<resource>的rlimit(资源限制)
19.start<service>
启动指定服务(如果此服务还未运行)。
20.stop<service>
停止指定服务(如果此服务在运行中)。
21.symlink<target><path>
创建一个指向<path>的软连接<target>。
22.sysclktz<mins_west_of_gmt>
设置系统时钟基准(0代表时钟滴答以格林威治平均时(GMT)为准)
23.trigger<event>
触发一个事件。用于Action排队
24.wait<path>[<timeout>]
等待一个文件是否存在,当文件存在时立即返回,或到<timeout>指定的超时时间后返回,如果不指定<timeout>,默认超时时间是5秒。
25.write<path><string>[<string>]*
向<path>指定的文件写入一个或多个字符串。
lservice
Services(服务)是一个程序,他在初始化时启动,并在退出时重启(可选)。Services(服务)的形式如下
serviceservicemanager/system/bin/servicemanager
classcore
usersystem
groupsystem
critical
onrestartrestartzygote
onrestartrestartmedia
onrestartrestartsurfaceflinger
onrestartrestartdrm
lOptions
Option是针对Service的选项,可以影响服务如何以及怎样运行。服务支持的选项如下:
1.critical
表明这是一个非常重要的服务。如果该服务4分钟内退出大于4次,系统将会重启并进入Recovery(恢复)模式。
2.disabled
表明这个服务不会同与他同trigger(触发器)下的服务自动启动。该服务必须被明确的按名启动。
3.setenv<name><value>
在进程启动时将环境变量<name>设置为<value>。
4.socket<name><type><perm>[<user>[<group>]]
Createaunixdomainsocketnamed/dev/socket/<name>andpass
itsfdtothelaunchedprocess.<type>mustbe"dgram","stream"or"seqpacket".
Userandgroupdefaultto0.
创建一个unix域的名为/dev/socket/<name>的套接字,并传递它的文件描述符给已启动的进程。<type>必须是"dgram","stream"或"seqpacket"。用户和组默认是0。
5.user<username>
在启动这个服务前改变该服务的用户名。此时默认为root。
6.group<groupname>[<groupname>]*
在启动这个服务前改变该服务的组名。除了(必需的)第一个组名,附加的组名通常被用于设置进程的补充组(通过setgroups函数),档案默认是root。
7.oneshot
服务退出时不重启。
8.class<name>
指定一个服务类。所有同一类的服务可以同时启动和停止。如果不通过class选项指定一个类,则默认为"default"类服务。
9.onrestart
当服务重启,执行一个命令