init.rc概述
init.rc是Androrid的可配置初始化文件,其由init负责解析,在定制开发下可在init.rc中添加指令来改变系统启动过程。此配置文件使用的Android Init Language是一种类C风格的程序语言,主要由Actions、Commands、Services、Options四大板块的语句组成,一般一条语句占据一行,单词之间由空格分隔。
AIL语言的注释一般使用使用#符号开头,以下则分别就四个板块的语句来做说明。
Actions
Actions由多个Commands组成,其首部分包含一个trigger作为此Actions被执行的触发条件,当Actions满此条件时如果系统的执行队列中无此Actions则被加入到列尾以等待执行。
其语法格式如下:
on <trigger>
<command>
<command>
<command>
触发器用于描述Actions的触发条件,常见的trigger如下:
- boot init程序启动(即/init.conf被加载)后第一个被触发的trigger。
- = 当property被设置程特殊值时触发。
# 举个栗子
on property:sys.boot_from_charger_mode=1
class_stop charger
trigger late-init
- device-added-
当设备节点被添加时触发此形式trigger。 - device-removed-
当设备节点被移除时触发此形式trigger。 - service-exited- 指定的service退出时触发。
- early-init 在init.c妈的main函数中最早触发的Actions(解析完init.rc之后立即触发)。
- init 在init.c中触发。
- late-init 在init.c中触发,late-init与charger两种触发器是对立的。
Services
Services指的是那些在init时需要启动或者在service意外退出后需要restart的程序。其语法格式如下:
service <name> <pathname> [ <argument> ]*
<option>
<option>
...
- 标识启动服务的名称。
- 当前服务对应程序的位置。
- 服务启动参数。
- 影响如何及何时init程序启动此服务。
以下是init.rc中Zygote进程启动方式:
# 第一个java进程Zygote
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
Options
Options是services的修饰语句,其影响了services如何+何时有init程序启动。以下是各个option及其释义:
- critical, 标识此service是设备关键服务,如果此类型service在四分钟内exit四次以上,则设备会重启并进入recovery模式。
service ueventd /sbin/ueventd
class core
# 指明ueventd是关键服务
critical
seclabel u:r:ueventd:s0
- disabled, 标识此服务在class类型匹配情况下不会自行启动,只会在明确调用service名称是才会启动。
# adbd is controlled via property triggers in init.<platform>.usb.rc
service adbd /sbin/adbd --root_seclabel=u:r:su:s0
class core
socket adbd stream 660 system system
# 此处指明adbd服务是在init.usb.rc中被显式启动
disabled
seclabel u:r:adbd:s0
- setenv , 在service启动进程中设置环境变量的值为。
- socket [ [ [ ] ] ],在/dev/socket/目录下创建名称为的unix domain socket,并把其文件描述符fd传给被启动的服务进程。的类型只能为"stream"或者"seqpacket"。
- user ,在启动此service之前改变用户至,当前默认用户为root。如果当前service需要使用linux的某些capabilities时则不能使用此option,而是需要在root下在service进程中申请使用这些capabilities。
- group [ ]*,在启动此service之前改变用户组至,默认为root组。
- seclabel ,主要在启动service之前切换上下文环境。此option主要用于从rootfs启动的服务如ueventd, adbd等。如不设置,则默认为init上下文环境。
- oneshot,当service退出时不重启此service。
service bootanim /system/bin/bootanimation
# 归类为core
class core
# 此处声明开机动画所在用户及用户组
user graphics
group graphics audio
# 声明bootanim不会随着class_start core(在boot触发器中触发)而启动
disabled
#此处指明开机动画退出后不重启。
oneshot
- class , 声明此service的类型,所有处于同一class类型的service会被同时启动或同时停止。如果不设置则默认为"default"类型。
- onrestart,当服务重新启动时执行一条指令。
下边举两个service应用option的例子:
1. servicemanager服务的启动
service servicemanager /system/bin/servicemanager
class core
user system
group system
critical
onrestart restart healthd
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
onrestart restart drm
2. 开机动画service的启动
service bootanim /system/bin/bootanimation
class core
user graphics
group graphics audio
disabled
oneshot
Commands
- exec
[ ]*,阻塞式执行指定path下的程序,并向其传递参数argument,此command需慎用,可能会导致init程序超时异常。 - export ,设置全局变量的值为。
- ifup ,激活指定的网络接口。
- import ,用于导入init config文件以扩展当前文件配置。
- hostname ,设置当前设备的主机名。
# 在boot时设置设备网络相关,关于boot的触发则在late-init中进行。
on boot
# basic network init
ifup lo
hostname localhost
domainname localdomain
...
- chdir ,改变当前工作目录。
- chmod
,改变指定目录文件 的读写权限。 - chown
,改变指定目录文件的所属用户及用户组。 - chroot ,改变进程所在根目录。
- class_start ,启动所有标记为此class类型的未启动的service。
on boot
...
# 在boot中把相关的command都完成后,启动核心服务如ueventd、lmkd、servicemanager等。
class_start core
- class_stop ,停止所有标记为此class类型的正在运行的service。
- domainname ,设置域名。
- enable ,让声明为disable的服务处于enable状态,并同时启动此服务。此command典型的应用是当bootloader的某一变量等于某值时需要启动某service。
on property:ro.boot.myfancyhardware=1
enable my_fancy_service_for_my_fancy_hardware
- insmod
,安装某模块到指定的 下。 - mkdir
[mode] [owner] [group],创建一个指定 的目录,并可指定该目录的读写权限及所属用户及用户组,如不指定权限则默认为755,如不指定用户/用户组则默认为根用户及根用户所在组。
on init
...
# android常见的目录创建在init触发器中进行
mkdir /system
mkdir /data 0771 system system
mkdir /cache 0770 system cache
mkdir /config 0500 root root
...
- mount
[ ]*,用于挂载指定目录 下名称为的设备。
mount tmpfs tmpfs /mnt/asec mode=0755,gid=1000
- restorecon
[ ]*,恢复指定 文件的安全上下文(security context)到file_contexts配置文件中所指示的那样。如果该 文件是在init.rc中创建的则无需此command声明,因为其已经自动被init程序标记了安全上下文。 - restorecon_recursive
[ ]*,递归恢复指定目录 下的所有文件的安全上下文。 - setcon ,设置当前进程的安全上下文,此command只在触发器为early-init的Action中设置init程序的上下文使用(如以下)。
setcon u:r:init:s0
- setenforce 0|1,设置SELinux(访问控制安全系统)的强制状态,0表示permissive自由状态,1表示enforcing强制状态。
- setkey
- setprop ,设置系统属性的值为。
setprop selinux.reload_policy 1
- setrlimit ,设置资源的访问限制。
# set RLIMIT_NICE to allow priorities from 19 to -20
setrlimit 13 40 40
- setsebool ,设置SELinux的布尔变量的值为。
- start ,启动一个未处于运行状态的服务。
# 当trigger条件成立启动surfaceflinger等服务
on property:vold.decrypt=trigger_encryption
start surfaceflinger
start encrypt
- stop ,如果指定服务正在运行,则停止此服务。
- symlink
,创建一个指向 的符合链接。
# Backward compatibility
symlink /system/etc /etc
symlink /sys/kernel/debug /d
# Right now vendor lives on the same filesystem as system,
# but someday that may change.
symlink /system/vendor /vendor
- sysclktz <mins_west_of_gmt>,设置系统基准时间,值0表示格林尼治时间。
on init
# android默认使用格林尼治时间
sysclktz 0
...
- trigger ,用于触发事件,通常该触发器指示的会进入init程序中的action队列中等待执行。例如late-init中指示一系列待执行事件入队。
# Mount filesystems and start core system services.
on late-init
trigger early-fs
trigger fs
trigger post-fs
trigger post-fs-data
# Load properties from /system/ + /factory after fs mount. Place
# this in another action so that the load will be scheduled after the prior
# issued fs triggers have completed.
trigger load_all_props_action
# Remove a file to wake up anything waiting for firmware.
trigger firmware_mounts_complete
trigger early-boot
trigger boot
- wait
[ ],返回指定 下文件的存在与否,如存在则立即返回,否则在超时后返回,默认的超时时间为5s。 - write
,写入内容到指定路径 的文件中。
on early-init
# 设置init进程的进程优先级(防止oom时被kill)为最低
write /proc/1/oom_score_adj -1000