介绍

介绍init.rc,就要从init说起。init是Android的Linux内核启动的第一个进程,它的PID永远是1,并且该进程不会死亡,一旦死亡内核就崩溃了。init进程启动后会fork出很多重要的系统进程,比如zygote进程。而init.rc差不多就是这个init进程的配置文件,主要来规定init进程的行为和动作。

语法

一个完整的init.rc 脚本由4中类型声明组成。即:

  • Action(动作)
  • Commands(命令)
  • Services(服务)
  • Options(选项)

    Action 和Services 表明一个新语句的开始,这两个关键字后面跟着的Commands 或者 Options 都是属于这个语句;
    Action 和Services 都有唯一的名字,如果出现动作或者服务重名,则会被当做错误处理。

Action(动作)

语法格式:

on <trigger>   ##触发条件
     <command1>  ##执行命令
     <command2>  ##可以同时执行多个命令
     <command3>

<trigger>条件满足时,依次执行后面的command,如

举例说明:下面这句话的意思是当属性值满足persist.service.adb.enable=1时,启动adbd 进程;
on property:persist.service.adb.enable=1
   start adbd

常见的<trigger>

trigger Description
boot init程序启动后触发的第一个事件
< name>=< value> 当属性< name> 满足< value>时触发
device-added/removed-< patch> 当设备节点添加/删除时触发此事件
sevice-exited-< name> 当指定服务< name> 存在时触发

常见的<Commands>

Command Description
exec < path> [< argument>]* Fork 并执行一个程序,其路径为< path>。该命令将阻塞 直到该程序启动完成
export < name> < value> 设置某个环境变量< name> 的值为< value>。对全局有效,之后的进程都将继承这个变量
ifup < interface> 使网络接口< interface> 成功连接
import < filename> 解析另一个配置文件< filename>,以扩展当前配置
chdir < directory> 更换工作目录为< directory>
chmod < octal-mode> < path> 更改文件访问权限
chown < owner> < group> < path> 更改文件所有者和群组
mount < type> < device> < dir> [< mountoption>]* 尝试在指定路径上挂载一个设备
start < service> 启动一个服务,如果它没有处于运行状态的话
stop < service> 停止一个服务,如果它当前处于运行状态的话
setprop < name> < value> 设置系统属性< name> 的值为 < value>
trigger < event> 触发一个事件

Services(服务)

语法格式:

service <name> <pathname> [ <argument> ]*
        <option>
        <option>
        ...

说明:

  • < name>: 表示service 的名字;
  • < pathname>: 表示service所在路径,此处的service是可执行文件,所以一定有存储路径;
  • < argument>: 启动service所带的参数;
  • < option>: 对此service的约束选项,后面将详细讲解;
    例:
    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

常见的<option>

Option Description
critical 表明这是对设备至关重要的服务;如果它在四分钟内退出超过四次,则设备将进入Recovery 模式
disabled 表示此服务是不会自动启动,而是需要通过显示调用服务名来启动
setenv < name> < value> 设置环境变量< name> 为值< value>
socket < name> < type> < perm> [< user> [< group>] ] 创建一个名为dev/socket/< name>的 socket,然后将它的fd值传给启动它的进,有效的< type>值包括dgram,stream 和seqpacket。ueser 和group 的默认值为0。
user < username> 在启动服务前将用户切换至< username>,默认情况下用户都是root。
group < groupname> [< groupname>]* 在启动服务前将用户组切换至< groupname>
oneshot 当此服务退出时,不要主动去重启它
class < name> 为该服务指定一个class名。同一个class的所有服务必须同时启动或者停止。默认情况下服务的class名是“default”
onrestart 当此服务重启时,执行某些命令

妙用

  1. 开机完毕写寄存器:
    on property:sys.boot_completed=1
        write /sys/kernel/debug/spmi/spmi-0/address 0xa140
        write /sys/kernel/debug/spmi/spmi-0/data 0x1a
  2. 创建一个native service,在系统启动完毕后执行某脚本,完成简单的任务
    on property:sys.boot_completed=1
    start service_set_bkl
    service service_set_bkl /system/bin/setBKL.sh
        user root
        group root
        disabled
        oneshot

    参考

  3. init.rc 语法与解析
  4. Init.rc妙用及语法说明