Android init.rc 文件规则详解

Android init.rc 文件规则详解

本文属于原创,转载请声明。

前言

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

....
文件中个格式分为两种类型:actionservice

1.action

action的格式:

on      #trigger 是判断的条件
        #command 是要执行的命令
    
    ...
trigger触发条件一般有以下几种:
  • boot/init
    例如on boot 或者 on init

  • name=value
    一般是检测某个系统参数是否等于某个值 例如上文中的
    on property:vold.decrypt=trigger_encryption

  • device-added-/device-removed-
    当一个设备被添加或者删除时。

  • service-exited- 当某个服务退出时。


command一般有以下几种:
  • ifup 启动网卡

  • insmod 安装模块

  • start/stop 启动、停止某个服务

  • setprop 设置系统参数

  • class_start / class_stop
    启动和停止某一类的服务

  • symlink 创建符号链接

  • chmod / chown 修改文件权限

2.service

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脚本 。设置运行的usergroup,设置为不自动启动disabled,设置为退出之后不重启oneshot

当属性 sys.wifi.on=true时,就会启动goio_read这个服务。


四.特殊情况说明(selinux)

Android 基于Linux引入了selinux,这是专门为Linux设计的一套安全机制。会限制系统的种种权限,下文仅对init.rc中启动的权限进行说明。

selinux 有三种权限:disabledpermissionenforcing

android 6.0之前的版本能将selinux设置成disabled,但6.0直接关闭会带来很多奇怪的现象,一般不建议关闭。建议在开发阶段设回可以设置成permission,省掉一大堆权限问题,等功能实现之后有需要再修改成enforcing,,再根据提示和selinux的规范添加相应的.te文件来增加权限。

查看系统现在处于selinux的什么状态:
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 的状态。

修改selinux的方法:

不同平台有很大的差异性,下面贴出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服务正常使用
假设现在处于’permissive’

在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规则的生成可以使用工具:





你可能感兴趣的:(Android系统)