• init.rc语法与解析


    init进程是Android系统中用户空间的第一个进程,进程ID为1,源代码位于system/core/init 目录。作为Android系统的第一个进程,Init进程承担这很多重要的初始化任务,一般Init进程的初始化可以分为两部分,前半部分挂载文件系统,初始化属性系统和Klog, selinux的初始化等,后半部分重要通过解析init.rc来初始化系统daemon服务进程,然后以epoll的监控属性文件,系统信号等。

    init.rc则是init进程启动的配置脚本,这个脚本是用一种叫Android Init Language(Android初始化语言)的语言写的。在7.0以前,init进程只解析根目录下的init.rc文件,但是随着版本的迭代,init.rc越来越臃肿,在7.0以后,init.rc一些业务被拆分到/system/etc/init/vendor/etc/init/odm/etc/init 三个目录下。

    init.rc包括四种类型的语句:

    • 动作 Action
    • 命令 Command
    • 服务 Service
    • 选项 Option
    1. Action和Service隐式定义了一个新的section(段),所有Command或Option属于最近定义的section。在第一个section之前的Command或Option将被忽略。
    2. Action 和Services 都有唯一的名字,如果出现动作或者服务重名,则会被当做错误处理。
    3. 所有语句都是面向行的,以空格分割每行包含的若干token。C风格的反斜杠可以用于token中插入空格,双引号同样可以避免空格将文本分为多个token。反斜杠是一行的最后一个字符时,将用于续行。
    4. 以#开头的行(前面有空格也是允许的)是注释。

    动作 Action

    语法格式

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

    Action是有名字的一系列的命令。Action有一个trigger(触发器),用于决定该Action应在何时执行。当一个事件发生并匹配了一个Action的trigger,相应的Action将被添加到即将执行(to-be-executed)队列的尾部(除非该Action存在与队列上了)。

    每个action在队列中顺序排列,每个action中的command将会顺序执行。init在执行command的过程中同时会执行其他活动(设备节点的创建/销毁,属性设置,进程重启)。

    init.rc中常见的trigger如下:

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

    下面列举两种常见的Action定义代码:

    #当init被触发时执行
    on init
      <command>
      ...
    #当属性sys.boot_completed被设置为1时执行
    on property:sys.boot_completed=1
      <command1>
      ...
    

    命令 Command

    init.rc中常见的Commands有以下一些:

    • exec <path> [ <argument> ]*
      创建和执行程序(). 这将会阻塞init,直到程序执行完成。由于它不是内置命令,应尽量避免使用exec,它可能会引起init卡死。
    • export <name> <value>
      在全局环境变量中设在环境变量 <name><value>。(这将会被所有在这命令之后运行的进程所继承)
    • ifup <interface>
      启动网络接口<interface>
    • import <filename>
      解析一个init配置文件,扩展当前配置。
    • hostname <name>
      设置主机名。
    • chdir<directory>
      改变工作目录。
    • chmod <octal-mode> <path>
      更改文件访问权限。
    • chown <owner> <group> <path>
      更改文件的所有者和组。
    • chroot <directory>
      改变进程的根目录。
    • class_start <serviceclass>
      启动该类service所有尚未运行的服务。
    • class_stop <serviceclass>
      停止所有该类正在运行的service。
    • domainname <name>
      设置域名。
    • enable <servicename>
      改变一个disable的service为enabled。一般用于service在init.rc中被标记为disabled,这样的service是不会被启动的,当满足一定的触发条件时,可以同enable命令来将他变为enabled。示例:
      on property:boot_completed=1
      enable my_service_name
    
    • insmod <path>
      安装位于<path>的模块(PS:驱动)。
    • mkdir <path> [mode] [owner] [group]
      <path>创建一个目录,(可选)使用给定的模式,所有者个组。如果没有提供,该目录将用755权限,所有者为root用户,组为root。
    • mount <type> <device> <dir>[ <mountoption> ]*
      尝试挂载<device><dir><device>可能有mtd@name形式,以指定名为name的mtd块设备。 <mountoption>包括 "ro", "rw", "remount", "noatime", ...
    • restorecon <path> [ <path> ]*
      恢复名为<path>的文件在file_contexts中配置的的安全级别。自动被init标记正确,不需要用init.rc创建的目录。
    • restorecon_recursive <path> [ <path> ]*
      递归的恢复<path>指出的目录树中file_contexts配置指定的安全级别。 path不要用shell可写或app可写的目录,如/data/locla/temp/data/data,或者有类似前缀的(目录)。
    • setcon <securitycontext>
      设置当前进程的security context为特定的字符串。这是典型的仅用于所有进程启动之前的early-init设置init context
    • setenforce 0|1
      设置SELinux系统范围的enfoucing状态。0 is permissive (i.e. log but do not deny), 1 is enforcing.
    • setprop <name> <value>
      设置系统属性<name><value>.
    • setrlimit <resource> <cur> <max>
      为特定资源设置rlimit
    • setsebool <name> <value>
      设置SELinux的bool类型<name><value><value> may be 1|true|on or 0|false|off
    • start <service>
      启动一个服务(如果服务尚未启动)。
    • stop <service>
      停止服务(如果正在运行)。
    • symlink <target> <path>
      创建一个符号连接,at <path> with the value <target>
    • sysclktz <mins_west_of_gmt>
      Set the system clock base (0 if system clock ticks in GMT)
    • trigger <event>
      触发一个事件。一个动作将另一动作排队。
    • wait <path> [ <timeout> ]
      poll特定的<path>,出现后返回,或timeout到达。如果timeout没有指定,默认为5秒。
    • write <path> <string>
      打开一个位于<path>的文件,写入(不是追加)字符串<string>

    服务 Service

    语法格式

    service <name> <pathname> [ <argument> ]*
         <option>
         <option>
         ...
    
    • <name> ——表示service 的名字;
    • <pathname> ——表示service所在路径,此处的service是可执行文件,所以一定有存储路径;
    • <argument> ——启动service所带的参数;
    • <option> ——对此service的约束选项,后面将详细讲解;

    选项 Option

    Option用来定义Service的行为,决定了Service将在何时启动,如何运行等。常用的Option有包括以下一些。

    • critical
      这是十分关键的服务。如果在四分钟内退出超过四次,手机将会重启并进入recovery模式。
    • disabled
      这种类型的服务不会自动启动。它必须明确的使用名字启动。
    • setenv <name> <value>
      设置环境变量<name>=<value>在加载的进程中。
    • socket <name> <type> <perm> [ <user> [ <group> [ <context> ] ] ]
      创建一个名为/dev/socket/<name>的UNIX域socket并将fd传递到加载的进程中。

    <type>必须是"dgram", "stream", "seqpacket"中的一种。
    <user><group>默认为0.
    <context>是 SELinux socket 安全上下文,默认为service安全级别,可以指定为seclabel或根据service的可执行文件的安全级别计算。

    • user <username>
      在执行该service前改变用户名,默认为root。如果你的进程请求Linux的特殊能力,就不要用这个命令。需以进入进程仍是root->请求特权->切换到你期望的uid来替换此法。
    • group <groupname> [ <groupname> ]*
      在执行该service前改变组名。第一个以后的附加组名用于设定进程的附加组(通过setgroups())。当前默认是root。
    • seclabel <securitycontext>
      在执行服务之前改变安全级别。主要用于从rootfs执行服务,比如ueventd, adbd. 在system分区上可以用基于文件安全级别的策略定义的transition,如果没有指定且没有定义策略的transition,默认是init上下文。
    • oneshot
      退出不重启服务(名副其实,一次性)。
    • class <name>
      为一service指定一个类名,所有有相同类名的service可以一同启动或停止。如果没有用class选项指定类名,该service属于"default"。
    • onrestart
      在service重启的时候执行。

    引用:http://www.ccbu.cc/index.php/framework/51.html

  • 相关阅读:
    -webkit-line-clamp 多行文字溢出...
    整理一些知识碎片...
    localstorage sessionstorage和cookie的区别
    数据结构 --- Set
    Iterator(遍历器)
    ES6数组方法 -- reduce()
    ES6 -- 展开运算符
    Centos7 + Oracel 18c
    Mysql 查询返回大量数据导致内存溢出
    github的安装和使用
  • 原文地址:https://www.cnblogs.com/lixuejian/p/15157634.html
Copyright © 2020-2023  润新知