Android8.0系统启动流程之语法规则(六)
1、概述
init经过前两个阶段后,已经建⽴了属性系统和SELinux系统,但是init进程还需要执⾏很多其他的操作,还要启动许多关键的系统服务,但是如果都是像属性系统和SELinux系统那样⼀⾏⾏代码去做,显得有点杂乱繁琐,⽽且不容易扩展,所以Android系统引⼊了
<。
是init进程启动的配置脚本,这个脚本是⽤⼀种叫Android Init Language(Android初始化语⾔)的语⾔写的,在7.0以前,init进程只解析根⽬录下的⽂件,但是随着版本的迭代,越来越臃肿,所以在7.0以后,⼀些业务被分拆
到/system/etc/init,/vendor/etc/init,/odm/etc/init三个⽬录下,在本篇⽂章中,将先解释的⼀些语法。
2、Android Init Language语法
定义在platform/system/core/init/README.md
.rc⽂件主要配置了两个东西,⼀个是action,⼀个是service,trigger和command是对action的补充,options是对service的补充。action加上trigger以及⼀些command,组成⼀个Section;service加上⼀些option,也组成⼀个Section ;.rc⽂件就是由⼀个个Section 组成。.rc⽂件头部有⼀个import的语法,表⽰这些.rc也⼀并包含并解析,接下来我们重点讲下action和service.
2.1 action
action的格式如下:
on <trigger> [&& <trigger>]*
<command>
<command>
<command>
以on开头,trigger是判断条件,command是具体执⾏⼀些操作,当满⾜trigger条件时,执⾏这些command。
trigger可以是⼀个字符串,如:
on early //表⽰当trigger early或QueueEventTrigger("early")调⽤时触发
也可以是属性,如:
on property:sys.boot_from_charger_mode=1//表⽰当sys.boot_from_charger_mode的值通过property_set设置为1时触发
on property:p_def_init_rwnd=* // *表⽰任意值
条件可以是多个,⽤&&连接,如:
//表⽰当zygote-start触发并且ro.crypto.state属性值为unencrypted时触发
on zygote-start && pto.state=unencrypted
command就是⼀些具体的操作,如:
mkdir /dev/fscklogs 0770 root system //新建⽬录制作android软件流程
class_stop charger //终⽌服务
trigger late-init //触发late-init
2.2 service
services的格式如下:
service <name> <pathname> [ <argument> ]*
<option>
<option>
...
以service开头,name是指定这个服务的名称,pathname表⽰这个服务的执⾏⽂件路径,argument表⽰执⾏⽂件带的参数,option 表⽰这个服务的⼀些配置。
⼀个典型的例⼦;如:
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
priority -20
user root
group root readproc
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
这个是配置在 /⽂件中的service, 它就是我们常说的zygote进程的启动配置。zygote是进程名,可执⾏⽂件路径
在/system/bin/app_process64,执⾏⽂件参数(就是可执⾏程序main函数⾥⾯的那个args)是
-Xzygote /system/bin –zygote –start-system-server –socket-name=zygote
后⾯的option是⼀些服务配置,⽐如:class main表⽰所属class是main,相当于⼀个归类,其他service也可以归为main,他们会被⼀起启动或终⽌,service有⼀个name,也有⼀个class,就像⼯作中,你有⼀个名字叫foxleezh,也可以说你属于android部门.
2.3 Options
Options是Services的参数配置. 它们影响Service如何运⾏及运⾏时机
console
console [<console>]
Service需要控制台. 第⼆个参数console的意思是可以设置你想要的控制台类型,默认控制台是/dev/console ,
/dev 这个前缀通常是被忽略的,⽐如你要设置控制台 /dev/tty0 ,那么只需要设置为console tty0
critical
critical
表⽰Service是严格模式. 如果这个Service在4分钟内退出超过4次,那么设备将重启进⼊recovery模式
disabled
disabled
表⽰Service不能以class的形式启动,只能以name的形式启动
setenv
setenv <name> <value>
在Service启动时设置name-value的环境变量
socket
socket <name> <type> <perm> [ <user> [ <group> [ <seclabel> ] ] ]
创建⼀个unix域的socket,名字叫/dev/socket/name , 并将fd返回给Service. type 只能是"dgram", "stream"
or"seqpacket".User 和 group 默认值是0.'seclabel'是这个socket的SELinux安全上下⽂,它的默认值是
service安全策略或者基于其可执⾏⽂件的安全上下⽂.它对应的本地实现在libcutils的android_get_control_socket
file
file <path> <type>
打开⼀个⽂件,并将fd返回给这个Service. type只能是"r", "w"or"rw". 它对应的本地实现在libcutils的
android_get_control_file
user
user <username>
在启动Service前将user改为username,默认启动时user为root(或许默认是⽆).在Android M版本,如果⼀个进程想拥有Linux capabilities(相当于Android中的权限吧),也只能通过设置这个值. 以前,⼀个程序要想有Linux
capabilities,必须先以root⾝份运⾏,然后再降级到所需的uid.现在已经有⼀套新的机制取⽽代之,
它通过fs_config允许⼚商赋予特殊⼆进制⽂件Linux capabilities. 这套机制的说明⽂档在
source.android/devices/tech/config/filesystem.html.当使⽤这套新的机制时,
程序可以通过user参数选择⾃⼰所需的uid,⽽不需要以root权限运⾏. 在Android O版本,程序可以通过
capabilities参数直接申请所需的能⼒,参见下⾯的capabilities说明
group
group <groupname> [ <groupname>\* ]
在启动Service前将group改为第⼀个groupname,第⼀个groupname是必须有的,
默认值为root(或许默认值是⽆),第⼆个groupname可以不设置,⽤于追加组(通过setgroups).
capabilities
capabilities <capability> [ <capability>\* ]
在启动Service时将capabilities设置为capability. 'capability'不能是"CAP_" prefix, like "NET_ADMIN"
or"SETPCAP". 参考/linux/man-pages/man7/capabilities.7.html ,
⾥⾯有capability的说明.
seclabel
seclabel <seclabel>
在启动Service前将seclabel设置为seclabel. 主要⽤于在rootfs上启动的service,⽐如ueventd, adbd.
在系统分区上运⾏的service有⾃⼰的SELinux安全策略,如果不设置,默认使⽤init的安全策略.
oneshot
oneshot
退出后不再重启
class
class <name> [ <name>\* ]
为Service指定class名字. 同⼀个class名字的Service会被⼀起启动或退出,默认值是"default",第⼆个name可以不设置,⽤于service组.
animation
animation class
animation class主要包含为开机动画或关机动画服务的service. 它们很早被启动,⽽且直到关机最后⼀步才退出.
它们不允许访问/data⽬录,它们可以检查/data⽬录,但是不能打开/data⽬录,⽽且需要在/data不能⽤时也正常⼯作。
onrestart
onrestart
在Service重启时执⾏命令.
writepid
writepid <file> [ <file>\* ]
当Service调⽤fork时将⼦进程的pid写⼊到指定⽂件. ⽤于cgroup/cpuset的使⽤,当/dev/cpuset/下⾯没有⽂件
但ro.cpuset.default的值却不为空时,将pid的值写⼊到/dev/cpuset/cpuset_name/tasks⽂件中
priority
priority <priority>
设置进程优先级. 在-20~19之间,默认值是0,能过setpriority实现
namespace
namespace <pid|mnt>
当fork这个service时,设置pid或mnt标记
oom_score_adjust
oom_score_adjust <value>
设置⼦进程的 /proc/self/oom_score_adj 的值为value,在 -1000~1000之间.
Triggers
Triggers
Triggers 是个字符串,当⼀些事件发⽣满⾜该条件时,⼀些actions就会被执⾏
Triggers分为事件Trigger和属性Trigger
事件Trigger由trigger 命令或QueueEventTrigger⽅法触发.它的格式是个简单的字符串,⽐如'boot'或'late-init'.
属性Trigger是在属性被设置或发⽣改变时触发. 格式是'property:<name>=<value>'或'property:<name>=*',它会在init初始化设置属性的时候触发.
属性Trigger定义的Action可能有多种触发⽅式,但是事件Trigger定义的Action可能只有⼀种触发⽅式
⽐如:
on boot && property:a=b 定义了action的触发条件是,boot Trigger触发,并且属性a的值等于b
on property:a=b && property:c=d 这个定义有三种触发⽅式:
在初始化时,属性a=b,属性c=d.
在属性c=d的情况下,属性a被改为b.
A在属性a=b的情况下,属性c被改为d.
2.4 Commands
bootchart
bootchart [start|stop]
启动或终⽌bootcharting. 这个出现在⽂件中,但是只有在/data/bootchart/enabled⽂件存在的时候才有效,
否则不能⼯作
chmod
chmod <octal-mode><path>
修改⽂件读写权限
chown
chown <owner><group><path>
修改⽂件所有者或所属⽤户组
class_start
class_start <serviceclass>
启动所有以serviceclass命名的未启动的service(service有⼀个name,也有个class,这⾥的serviceclass就是
class,class_start和后⾯的start是两种启动⽅式,class_start是class形式启动,start是name形式启动)
class_stop
class_stop <serviceclass>
终⽌所有以serviceclass命名的正在运⾏的service
class_reset
class_reset <serviceclass>
终⽌所有以serviceclass命名的正在运⾏的service,但是不禁⽤它们. 它们可以稍后被class_start重启
copy
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论