Fork me on GitHub
0%

init.rc语法及解析

在linux设备上输入“pstree”命令我们便会看到一棵进程树,不同状态不同设备树上进程名字进程号可能不完全一致,但进程号pid=1的进程一定是init进程!对于Android系统来讲,其实际是运行于Linux内核之上的一系列“服务进程”,而这些服务进程的“老祖宗”就是init,它是Android中第一个被启动的进程,所有服务都是通过解析init.rc文件得到的(部分可以执行程序通过init.d/文件夹下的脚本启动)

本篇文章将对init.rc文件语法进行解析

简介

查看andriod源码:http://androidxref.com/

init.rc是系统启动的第一个程序所加载的语法文件。init.rc文件是以“块”(section)为单位服务的,一个“块”(section)可以包含多行,而一行中包含多个tokens(符号)。“块”(section)分成两大类:一类称为”动作(action)”,另一类称为“服务(service)”。而一个init.rc脚本由四个类型的声明组成:

  1. 动作 :Actions,以关键字“on”开始
  2. 命令 :Commands,以关键字“start”“restart”“stop”开始
  3. 服务 :Services
  4. 选项 :Options

Actions

Actions就是响应某个事件的过程。如下所示当满足trigger触发条件时依次执行Commands命令。源码会依次将这些命令添加到“命令执行队列尾部”,系统对这些命令顺序执行。所以服务启动的根本就是on类型的section被执行的过程

1
2
3
4
on <trigger>        //触发条件
<command1> //命令1
<command2> //命令2
<command3> //命令3

对于trigger(触发器)来讲,常见的有两种形式:

  1. 单纯的字符串。例如:on boot
  2. 键值匹配,格式为“ on property = ”。例如:on property:init.svc.wifi = stopped

此外还有两种形式:

  1. device-added/removed- 当设备节点添加/删除时触发此事件
  2. sevice-exited- 当指定服务 存在时触发

Actions解析后执行顺序

1
2
3
4
5
6
7
8
9
10
on early-init           #在初始化早期阶段触发
on init #初始化阶段触发。这里会执行完属性服务,接下来就可以设置属性了
on late-init #在初始化晚期触发。在这里会通过trigger来执行其他的action,以下均是
on early-fs
on fs
on post-fs
on post-fs-data
on firmware_mounts_complete
on early-boot
on boot`

Commands

Command Description
start 启动一个服务,如果它没有处于运行状态的话
stop 停止一个服务,如果当前它处于运行状态的话
restart
setprop 设置的属性值为
trigger 触发一个事件
export 设置环境变量的值为,全局有效
mount []* 尝试在指定路径上挂载一个设备

Services

实际上每一个service就是一个可执行程序,它们在特定选项的约束下是被init程序运行或者重启(service可以在配置中指定是否需要退出重启,这样当service出现异常crash时就可以有机会复原)

1
2
3
4
5
6
7
8
service <name> <pathname> [ <argument> ]*
<option>
<option>
...
# <name> service服务的名字
# <pathname> service路径,一般对应可执行程序或者脚本
# <argument> 启动pathname下的service所需要的参数
# <option> service的约束项

Options

Option Description
disable 隐式声明,默认不会自动启动该服务,需要显式调用
oneshot 字面意思一次性,即服务退出时,不要主动重启该服务
onrestart 当服务重启时,执行某些命令(需要理解)
class 指定该服务属于class类,默认class名为default(注:同一个class所有服务必须是同时启动或停止)
socket [ [] ] 创建一个名为dev/socket/的 socket,然后将它的fd值传给启动它的进,有效的值包括dgram,stream 和seqpacket。ueser 和group 的默认值为0。
critical 表明这是对设备至关重要的服务;如果它在四分钟内退出超过四次,则设备将进入Recovery 模式
group []* 在启动服务前将用户组切换至
setenv 设置环境变量 为值

Notice

  1. service和Actions都是有唯一的名字的。如果有重名的情况会作为错误忽略。
  2. 无论是动作还是服务,并不是按照文件的编排顺序执行的。
  3. 该文件中注释以“#”开始;反斜杠“\”在行尾表示下面一行是同一行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/* 
* copy from http://androidxref.com/6.0.0_r5/xref/bootable/recovery/etc/init.rc
*/

import /init.recovery.${ro.hardware}.rc

on early-init
start ueventd
start healthd

on init
export PATH /sbin:/system/bin
export ANDROID_ROOT /system
export ANDROID_DATA /data
export EXTERNAL_STORAGE /sdcard

symlink /system/etc /etc

mkdir /sdcard
mkdir /system
mkdir /data
mkdir /cache
mkdir /sideload
mount tmpfs tmpfs /tmp

chown root shell /tmp
chmod 0775 /tmp

write /proc/sys/kernel/panic_on_oops 1
write /proc/sys/vm/max_map_count 1000000

on fs
mkdir /dev/usb-ffs 0770 shell shell
mkdir /dev/usb-ffs/adb 0770 shell shell
mount functionfs adb /dev/usb-ffs/adb uid=2000,gid=2000

write /sys/class/android_usb/android0/enable 0
write /sys/class/android_usb/android0/idVendor 18D1
write /sys/class/android_usb/android0/idProduct D001
write /sys/class/android_usb/android0/f_ffs/aliases adb
write /sys/class/android_usb/android0/functions adb
write /sys/class/android_usb/android0/iManufacturer ${ro.product.manufacturer}
write /sys/class/android_usb/android0/iProduct ${ro.product.model}
write /sys/class/android_usb/android0/iSerial ${ro.serialno}

on boot
ifup lo
hostname localhost
domainname localdomain

class_start default

# Load properties from /system/ + /factory after fs mount.
on load_all_props_action
load_all_props

on firmware_mounts_complete
rm /dev/.booting

# 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

on property:sys.powerctl=*
powerctl ${sys.powerctl}

service ueventd /sbin/ueventd
critical
seclabel u:r:ueventd:s0

service healthd /sbin/healthd -r
critical
seclabel u:r:healthd:s0

service recovery /sbin/recovery
seclabel u:r:recovery:s0

service adbd /sbin/adbd --root_seclabel=u:r:su:s0 --device_banner=recovery
disabled
socket adbd stream 660 system system
seclabel u:r:adbd:s0

# Always start adbd on userdebug and eng builds
on property:ro.debuggable=1
write /sys/class/android_usb/android0/enable 1
start adbd

# Restart adbd so it can run as root
on property:service.adb.root=1
write /sys/class/android_usb/android0/enable 0
restart adbd
write /sys/class/android_usb/android0/enable 1