Android Initial Language

作者: 特立独行的石头 | 来源:发表于2019-07-18 21:15 被阅读11次

    Android Initial Language

    1 概述

    Android Init Language,简称AIL,即安卓初始化语言。Android init进程解析的扩展名为rc文件就是用这种语言写的。

    所有语法规则都可以在readme.txt文件中获取。本文基于Android N的readme文件进行讲解,基本是对此文件的翻译,感觉翻译不到位的,可以查看原英文文件,路径如下:

    android/system/core/init/readme.txt

    2 语法

    安卓初始化语言由五大类语句组成,分别是Actions、Commands、Services、Options和Imports。

    所有这些都是以行为单位,各种记号由空格来隔开。C语言风格的反斜杠号可用于在记号间插入空格。双引号也可用于防止字符串被空格分割成多个记号。行末的反斜杠用于折行。

    注释行以井号(#)开头(允许以空格开头)。

    Actions和Services声明一个新的分组。所有的命令或选项都属于最近申明的分组。位于第一个分组之前的命令或选项将会被忽略。 Actions和Services有唯一的名字。如果Action出现重名,第二个Action的commands将被加在第一个的后面。如果Services出现重名,第二个将被忽略,并且会打印一条错误日志。

    2.1 Actions

    Actions其实就是一序列的Commands(命令)。Actions都有一个trigger(触发器),它被用于决定action的执行时间。当一个符合action触发条件的事件发生时,action会被加入到执行队列的末尾,除非它已经在队列里了。

    队列中的每一个action都被依次提取出,而这个action中的每个command(命令)都将被依次执行。Init在这些命令的执行期间还控制着其他的活动(设备节点的创建和注销、属性的设置、进程的重启)。

    Actions格式如下:

    image.png

    2.2 Triggers

    触发器本质上是一个字符串,能够匹配某种包含该字符串的事件。触发器又被细分为事件触发器(event trigger)和属性触发器(property trigger)。触发器是一个用于匹配特定事件类型的字符串,用于是Actions发生。

    事件触发器可由"trigger"命令触发,或初始化过程中通过QueueEventTrigger()触发,通常是一些事先定义的简单字符串,例如:boot,late-init。

    属性触发器是当指定属性的变量值变成指定值时触发,其格式为'property:<name>=<value>' and 'property:<name>=*'。

    一个Action可以有多个属性触发器,但是最多有一个事件触发器.

    下面我们看两个例子:

    on boot && property:a=b

    该Action只有在boot事件发生时,并且属性a和b相等的情况下才会被触发.

    on property:a=b && property:c=d

    该Action会在以下三种情况被触发:

    1)在启动时,如果属性a的值等于b并且属性c的值等于d

    2)在属性c的值已经是d的情况下,属性a的值被更新为b

    3)在属性a的值已经是b的情况下,属性c的值被更新为d

    触发器分为定义好的触发器和设置的触发器。

    2.2.1 定义好的触发器

    定义好的事件触发器有early-init\init\late-init,是在初始化过程中通过QueueEventTrigger()触发。

    early-init

    一些前置工作,创建mnt目录,挂载tmpfs等。

    init

    设置loglevel,建立符号链接,创建system/data/cache目录,proc/dev处理等。

    late-init

    触发用户设置的触发器。

    2.2.2 创建的触发器

    用户创建的触发器,通过2.2.1中某一个阶段的trigger命令触发。

    trigger <用户创建的触发器名称>

    触发某一触发器。

    2.3 Commands

    command有很多,请查阅readme.txt文件。

    2.4 Services

    Init启动的程序,可以选择要不要在退出后重启。格式如下:

    image.png

    2.5 Options

    Options是服务的修饰符,他们影响Init运行服务的方式和时间。

    Critical

    这是一项设备关键型服务。 如果它在四分钟内退出超过四次以上,设备将重启进入恢复模式。

    Class <name>

    指定服务的类名。 命名类中的所有服务可以一起启动或停止。 如果未通过class选项指定服务,则服务在类“default”中。

    Seclabel <seclabel>

    在执行此服务之前更改为“seclabel”。 主要供从rootfs运行的服务使用,例如 ueventd,adbd。 系统分区上的服务可以基于其文件安全上下文使用策略定义的转换。

    如果未指定且策略中未定义转换,则默认为init上下文。

    group <groupname> [ <groupname> ]*

    在执行此服务之前更改为groupname。 除了(必需的)第一个之外的其他组名用于设置过程的补充组(通过setgroups())。 目前默认为root。

    User <username>

    在执行此服务前更改为username。

    Oneshot

    服务退出后,不进行重启。

    onrestart <xxxx>

    当服务重启的时候,执行一条指令。

    Disabled

    此服务不会自动从其类开始。 它必须通过名称显式启动。

    socket <name> <type> <perm> [ <user> [ <group> [ <seclabel> ] ] ]

    创建名为/ dev / socket / <name>的unix域套接字,并将其fd传递给已启动的进程。 <type>必须是“dgram”,“stream”或“seqpacket”。 用户和组默认为0.'seclabel'是套接字的SELinux安全上下文。 它默认为服务安全性上下文,由seclabel指定或基于服务可执行文件安全性上下文计算。

    setenv <name> <value>

    在启动的进程中将环境变量<name>设置为<value>。

    ioprio <rt|be|idle> <0-7>

    设置IO优先级。

    writepid <file...>

    当进程创建的时候,把进程ID写到给定的文件里面。意味着cgroup / cpuset的使用。

    2.6 Imports

    import关键字不是一个命令,而是一个部分,并在包含它的.rc文件完成解析后立即处理。

    import <path>

    解析init配置文件,扩展当前配置。 如果<path>是目录,则目录中的每个文件都将被解析为配置文件。 它不是递归的,嵌套目录不会被解析。

    init可以执行imports的rc文件只有两次:

    1)在初始引导期间导入/init.rc时

    2)在mount_all期间在指定路径导入/ {system,vendor,odm} / etc / init /或.rc文件时

    2.7 Properties

    Init通过以下属性提供有关其负责的服务的信息。

    init.svc.<name>

    命名服务的状态("stopped", "stopping", "running", "restarting")。

    2.8 还有介绍systrace和bootchat,感兴趣可以研究一下。

    3 rc文件

    init语言用于带.rc文件扩展名的纯文本文件中。 这些通常是系统中多个位置中的多个,如下所述。

    /init.rc是主.rc文件,在执行开始时由init可执行文件加载。 它负责系统的初始设置。 它导入/init.${ro.hardware}.rc这是主要供应商提供的.rc文件。

    在mount_all命令期间,init可执行文件加载/ {system,vendor,odm} / etc / init /目录中包含的所有文件。 在文件系统挂载后,这些目录包含所有操作和服务。

    可以在mount_all命令行中指定路径,使其在指定的路径中导入.rc文件,而不是上面列出的默认路径。 这主要用于支持工厂模式和其他非标准引导模式。 三个默认路径一般用于正常引导过程。

    下面是这些路径的意图:

    1)/system/etc/init/放置SurfaceFlinger\MediaService\logcatd等核心系统条目。

    2)/vendor/etc/init/放置芯片方案商的soc核心功能需要的actions和daemons。

    3)/odm/etc/init/用于设备制造商,例如运动传感器或其他外围功能所需的操作或守护程序。

    所有Services应该有service条目在相应的init.rc文件中,这些服务的二进制文件在system、vendor、odm分区,rc文件在对应分区的/etc/init/目录。每个init .rc文件还应包含与其服务关联的任何操作。

    示例:位于system/core/logcat/目录中的logcatd.rc和Android.mk文件。 Android.mk文件中的LOCAL_INIT_RC宏在构建过程中将logcatd.rc放在/system/etc/init /中。 Init在mount_all命令期间加载logcatd.rc并允许运行服务并在适当时是actions如队列。

    根据其守护进程分解init .rc文件比以前使用的单片init .rc文件更受欢迎。 这种方法可确保init读取的唯一服务条目和init执行的唯一操作对应于其二进制文件实际存在于文件系统上的服务,而单片init .rc文件则不然。 当将多个服务添加到系统时,这另外将有助于合并冲突解决,因为每个服务将进入单独的文件。


    image.png

    相关文章

      网友评论

        本文标题:Android Initial Language

        本文链接:https://www.haomeiwen.com/subject/ksirlctx.html