本文属于原创,转载请声明。
init.rc
文件是 android
系统一个十分重要的文件,本文先忽略这个文件的解析的具体的运行,先从文件的规则讲起,先学会用,下一篇文章再讲 init
进程具体的代码分析。
终端:/init.rc
源码:/device/rockchip/rk322x/init.rc (其他平台,位置类似)
先看下面文件的部分代码,请打开 init.rc 文件边看边分析。
on property:vold.decrypt=trigger_encryption
start surfaceflinger
start encrypt
service surfaceflinger /system/bin/surfaceflinger
class core
user system
group graphics drmrpc
onrestart restart zygote
....
action
和 service
action的格式:
on #trigger 是判断的条件
#command 是要执行的命令
...
trigger
触发条件一般有以下几种:boot/init
例如on boot
或者 on init
name
=value
一般是检测某个系统参数是否等于某个值 例如上文中的
on property:vold.decrypt=trigger_encryption
device-added-
当一个设备被添加或者删除时。
service-exited-
当某个服务退出时。
command
一般有以下几种:ifup
启动网卡
insmod
安装模块
start/stop
启动、停止某个服务
setprop
设置系统参数
class_start
启动和停止某一类的服务
symlink
创建符号链接
chmod / chown
修改文件权限
service的结构:
service []*
name
表示这个服务的名字
pathname
表示这个服务对应的可执行文件
argument
表示运行这个可执行文件想带的参数,可有可无
option
一般有以下几种:
user
在启动服务之前,把用户名切换到username,默认是root
group
类似user,支持一个服务属于多个用户组
oneshot
只启动一次,关闭之后不重启
class
设定为某一个类别,使用上面的class_start可以启动同个类别中的所有服务,没有设置默认是“default”
disabled
添加进服务链表,但不自己启动,等待其他去调动启动
socket
创建socket
在实际应用场景中,最常见就是添加一个bin或者sh 文件开机或者特定情况下运行,下面举例运行一个脚本。
on property:sys.wifi.on=true
start gpio_read
service gpio_read /system/bin/gpio_read.sh
user root
group root
class main
disabled
oneshot
设置一个gpio_read
服务对应可执行文件 gpio_read.sh
脚本 。设置运行的user
和group
,设置为不自动启动disabled
,设置为退出之后不重启oneshot
。
当属性 sys.wifi.on=true
时,就会启动goio_read
这个服务。
Android 基于Linux引入了selinux,这是专门为Linux设计的一套安全机制。会限制系统的种种权限,下文仅对init.rc
中启动的权限进行说明。
selinux 有三种权限:disabled
,permission
,enforcing
android 6.0之前的版本能将selinux设置成disabled
,但6.0直接关闭会带来很多奇怪的现象,一般不建议关闭。建议在开发阶段设回可以设置成permission
,省掉一大堆权限问题,等功能实现之后有需要再修改成enforcing
,,再根据提示和selinux的规范添加相应的.te文件来增加权限。
root@tiny4412:/ # cat /proc/cmdline
cat /proc/cmdline
console=ttySAC0,115200n8 androidboot.console=ttySAC0 ctp=2 skipcali=y vmalloc=384m ethmac=1C:6F:65:34:51:7E androidboot.selinux=permissive lcd=S702
可以看到 androidboot.selinux=permissive
表明我们现在的系统处于,permissive 的状态。
不同平台有很大的差异性,下面贴出rk和全志平台的使用方法
全志
--- a/android/device/softwinner/dolphin-fvd-p1/BoardConfig.mk
+++ b/android/device/softwinner/dolphin-fvd-p1/BoardConfig.mk
-BOARD_KERNEL_CMDLINE := selinux=1 androidboot.selinux=enforcing
+BOARD_KERNEL_CMDLINE := selinux=1 androidboot.selinux=permissive
rk平台
比较方便,在烧录的时候使用的文件
parameter,文件会对selinux进行设置。
CMDLINE:console=ttyFIQ0 androidboot.selinux=disabled ...
在init.rc中增加了启动的服务之后,我们还需要修改一下内容:
在文件device/.../sepolicy/file_contexts
中
+/system/bin/gpio_read.sh u:object_r:rgpio_read_exec:s0
在同一个目录中增加gpio_read.te
文件
+type gpio_read, domain;
+type gpio_read_exec, exec_type, file_type;
+init_daemon_domain(gpio_read);
这样修改之后就能正常使用了。
enforcing
呢?(待增加图片)在前面的基础下,当有条件去触发运行这个服务时,会打印出一堆类似下面图片的懂。
我们根据打印的内容和te文件的规则可以得到下面的规则。
将规则增加到上面的gpio_read.te文件中去,然后重写编译,一般这个过程需要几次才能完全没有报错。
另外te规则的生成可以使用工具: