Android 进阶——系统启动之Android init.rc脚本解析

Posted CrazyMo_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 进阶——系统启动之Android init.rc脚本解析相关的知识,希望对你有一定的参考价值。

引言

前一篇文章总结道android init进程创建启动完毕后,Android 特有的adbd、Zygote、Service Manager(C++)核心进程和服务都已经启动了,是通过什么方式启动的呢?系列文章链接如下:

一、init.rc 脚本结构概述

init.rc文件是以section(块、段)为单位服务的,一个section可以包含多行。section主要分成:

  • action (动作,行为),以关键字"on" 开头,表示一堆命令
  • service(服务),以关键字“service”开头,表示启动某个进程的方式和参数

section以关键字"on"或者"service"开始,直到下一个"on"或者"service"结束,中间所有行都属于这个section。

section中的内容有些是“类shell”命令(即只是语法参照shell,实质上是init进程里单独实现的一套命令机制),有些是自定义的动作和服务

无论是action section还是service section块,并不是按照文件中的编码排序逐一执行的

二、init.rc脚本基本语法

init.rc 是基于AIL(Android Init Language)是一种非常简单的语言,主要用于定义初始化流程中需要做的事情。

整理翻译自aosp\\system\\core\\init\\README.md

  • C语言风格的反斜杠转义字符("")可以用来为参数添加空格。
  • 关键字和参数以空格分隔,每个语句以行为单位。
  • 行尾的反斜杠用来表示下面一行是同一行
  • 为了防止字符串中的空格把其切割成多个部分,我们需要对其使用双引号
  • 空行或注释行没有分割作用,注释用’#'开始

1、init.rc脚本的组成元素

一个init.rc脚本由四部分组成:

  • action——动作,行为

  • command——命令,启动

  • service—— native 服务(或者可执行程序)

    此处的service 并非Android 系统中的service 概念,应该不支持java 可执行文件和java 代码。

  • Options—— 选项

actionservice表示一个新语句的开始,紧跟其后的commands或者options都属于这个新语句。

actionservice的名称只能唯一,如果出现和已有动作或服务重名的,将会被当成错误忽略掉。

2、基本元素的语法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zc1NTLew-1615650539960)(asset/image-20210305093052647.png)]

2.1、action

Actions代表一组命令,一个action包含一个触发器,该触发器(trigger)决定了何时执行这个Action。即在什么情况下才能执行该Action中的定义命令。当一些条件满足触发器的条件时,该Action中定义的命令会被添加到要执行命令队列的尾部(如果这组命令已经在队列中,则不会再次添加),当对应的trigger(事件)触发时,依次从队列中并按顺序执行对应的command(同一事件可以对应多个命令)。通用格式如下:

Action都是以on开始,随后会定义trigger,接着便是为其定义commmands

on <trigger> [&& <trigger>]*
   <command>
   <command>
   <command>

例如

例如:
on boot
   setprop a 1
   setprop b 2

on boot
   # 初始化网络
    ifup lo
    hostname localhost
    domainname localdomain

2.2、trigger

在这里插入图片描述

触发器 trigger本质上是一个字符串,代表能够匹配某种包含该字符串的事件,在action里面的,on后面跟着的字符串是触trigger,它将决定对应的action的是否被执行。trigger又被细分为事件触发器(event trigger)属性触发器(property trigger)

理论上我们也可以在对应的源代码中模仿添加我们自己的触发器相应的机制。

  • 事件触发器——由trigger命令或初始化过程中通过QueueEventTrigger()触发,通常是一些事先定义的简单字符串,比如 on boot、on init等等,常用的事件触发器有:

    事件触发器说明
    bootinit.rc被装载后
    device-added-< path >指定设备被添加时
    device-removed-< path >指定设备被移除时
    service-exited-< name >在特定服务(service)退出时
    early-init初始化之前
    late-init初始化之后
    init初始化时
  • 属性触发器——当指定属性的变量值变成指定值时触发,其格式为property:< name >=*如果属性值在运行时设成了指定的值,则action中的对应的命令列表就会执行。。一个Action可以有多个属性触发器,但是最多有一个事件触发器。例如:

    on property:a=b && property:c=d
         <command>
         <command>
    

    上面这个action 在以下三种情况会执行:

    • 在启动时,若属性a的值等于b且属性c的值等于d
    • 在属性c的值已经是d时,属性a的值被更新为b
    • 在属性a的值已经是b时,属性c的值被更新为d

trigger 可以理解为事件,事实上Linux或者Android系统的重启就是通过属性触发器来触发的。

2.3、command

command是action的命令列表中的命令(或者是service中的选项 onrestart 的参数命令),为action设置了trigger后就需要定义对应的一组command,这样trigger在被触发时command才会被一个个地取出依次执行。

command 绝大部分就是shell 命令

在这里插入图片描述

2.4、service

service是一些在系统初始化时就启动或者退出时需要重启的程序,首先需要为服务定义名字,并指定程序路径,然后便是通过options来修饰服务,service 关键字后紧跟着的是服务名称,定义之后就可以使用start 服务名称形式来启动一个服务,service关键字以下的行称为options,每一个选项占用一行,通用格式如下:

service <name> <pathname> [ <argument> ]*
        <option>
        <option>
        ...
  • < name >——service的名称

  • < pathname >——service所在路径。因为是可执行文件,所以一定有存储路径

  • < argument >——启动service所带的参数

  • < options >——service的约束选项

2.5、options

options是service的约束项,还可以决定一个service何时以及如何运行。

在这里插入图片描述

2.6、import

用来引入一个要解析的其他.rc配置文件,通常用于当前配置文件的扩展 。通用格式如下

import <path>

如果path是个一个目录,则该目录下的每个.rc文件都被引入,在初始化过程中共有两次使用import来引入.rc文件。

  • 在初始化引导期间,引入/init.rc文件
  • 在执行mount_all命令时,依次引入/{system,vendor,odm}/etc/init/或者指定路径下的.rc文件

2.7、propertyies

Properties代表Init进程运行中的一些属性信息,在Init进程运行中,通过以下系统属性能够获取当前程序内部信息。

在这里插入图片描述

3、init.rc 文件(部分)简单解读

//引入其他要解析的rc文件
import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /init.usb.configfs.rc
import /init.${ro.zygote}.rc

#在trigger  early-init初始化之前执行以下command
on early-init
    # Set init and its forked children's oom_adj.
    write /proc/1/oom_score_adj -1000
    # Disable sysrq from keyboard
    write /proc/sys/kernel/sysrq 0
    # Set the security context of /adb_keys if present.
     restorecon /adb_keys
    # Shouldn't be necessary, but sdcard won't start without it. http://b/22568628.
    mkdir /mnt 0775 root system

    # Set the security context of /postinstall if present.
    restorecon /postinstall
    #启动ueventd服务
    start ueventd
    
#定义ueventd服务,并设置服务路径为/sbin/ueventd 无参数
service ueventd /sbin/ueventd
    class core#为其设置类名为core
    critical#表明这是一个关键服务
    seclabel u:r:ueventd:s0 #设置其安全上下文

未完待续…

以上是关于Android 进阶——系统启动之Android init.rc脚本解析的主要内容,如果未能解决你的问题,请参考以下文章

Android 进阶——系统启动之SystemServer创建并启动Installer服务

Android 进阶——系统启动之SystemServer创建并启动Installer服务

Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动

Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动

Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动

Android 进阶——系统启动之核心SystemServer进程启动详解