Android init.rc文件

作者 by adtxl / 2021-02-04 / 暂无评论 / 529 个足迹

最好直接去看Android的官方文档,那里更完整准确,system/core/init/README.md

1. 文件简介

Android init.rc文件由系统第一个启动的init程序解析,此文件由语句组成,主要包含了四种类型的语句:Action,Commands,Services,Options.在init.rc文件中一条语句通常是占据一行.单词之间是通过空格符来相隔的.如果需要在单词内使用空格,那么得使用转义字符”\”,如果在一行的末尾有一个反斜杠,那么是换行折叠符号,应该和下一行合并成一起来处理,这样做主要是为了避免一行的字符太长,与C语言中的含义是一致的。注释是以#号开头。 Action和services显式声明了一个语句块,而commands和options属于最近声明的语句块。在第一个语句块之前 的commands和options会被忽略.

init.rc:Android在启动过程中读取的启动脚本文件,主要完成一些初级的初始化,在/system/core/init/init.cpp中解析。rc 经常被用作程序之启动脚本的文件名。它是“run commands”(运行命令)的缩写。

init.xx.rc:与具体CPU相关的启动脚本,比如对于MTK的CPU,名字为init.usb.rc,init.trace.rc。在init.rc之后得到解析。

厂商的rc文件一般位于device目录

2.init.rc和init.xx.rc文件的修改

我们以 init.rc 来入手,学习 rc 的用法。

2.1 文件结构

init.rc 基本单位是 section(语句块)。一个Section以Service或On开头的语句块.以Service开头的Section叫做服务,而以On开头的叫做动作(Action).

services: 服务.
Action: 动作
commands:命令.
options:选项.
trigger:触发器,或者叫做触发条件.
class: 类属,即可以为多个service指定一个相同的类属,方便操作同时启动或停止.

section 有三种类型:

  1. on
  2. service
  3. import

on 类型

作表示了一组命令(commands)组成.动作包含一个触发器,决定了何时执行这个动作。当触发器的条件满足时,这个动作会被加入到已被执行的队列尾。如果此动作在队列中已经存在,那么它将不会执行.
一个动作所包含的命令将被依次执行。动作的语法如下所示:

on <trigger>
    <command>
    <command>
    ...

on 类型 表示一系列的命令组合,eg:

on init
    # See storage config details at http://source.android.com/tech/storage/
    #mkdir /storage/sdcard 0555 root root

    #export EXTERNAL_STORAGE /storage/sdcard

    # Support legacy paths
    #symlink /storage/sdcard /sdcard
    #symlink /storage/sdcard /mnt/sdcard

    # mkdir /tmp 01775 root root
    # mount tmpfs tmpfs /tmp size=25m

    mkdir /dev/cpuctl/bg_non_interactive
    chown system system /dev/cpuctl/bg_non_interactive/tasks
    chmod 0666 /dev/cpuctl/bg_non_interactive/tasks

    # KSM config
    write /sys/kernel/mm/ksm/pages_to_scan 100
    write /sys/kernel/mm/ksm/sleep_millisecs 500
    write /sys/kernel/mm/ksm/run 1

    write /sys/block/zram0/comp_algorithm lz4
    write /sys/block/zram0/max_comp_streams 2

    # Swap in only 1 page at a time
    write /proc/sys/vm/page-cluster 0

这样一个 section 里面包含了多个命令。命令的执行是以 section 为单位的。
上面这些命令都会一起顺序执行,不会单独执行。

service 类型

服务是指那些需要在系统初始化时就启动或退出时自动重启的程序.
它的语法结构如下所示:

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

service 类型 的section 表示一个可执行的程序,下面是个人工作内容中片段代码:

service submcu_srv /vendor/bin/submcu_srv
    class core
    user root
    group root
    oneshot

submcu_srv作为一个名字标识了这个 service,这个可执行程序的位置在 /vendor/bin/submcu_srv
下面的oneshot 被称为 options,options 是用来描述的 service 的特点,不同的 service 有不同的 options。

service 的执行总存在于某个 on 类型的section 中作为一个服务启动的动作(Action)。例如,这个submcu_srv可以在on fs中启动

on fs
    export OMX_BELLAGIO_REGISTRY /vendor/etc/omxregister
    start submcu_srv

例二:

service yo_service1 /system/bin/yo_service1
    class core
    user system
    disabled
    group system radio shell
    oneshot

on yo_fs
    class_start core

其中 yo_service1 这个 service 的类型是 core。
在 yo_fs 被调用的时候则将会 class_start 而执行所有类型为 core 的 service。

options(选项)

选项是用来修饰服务的。它们影响如何及何时运行这个服务.
imaged85531f1b82577c4.png

trigger(触发器)

触发器用来描述一个触发条件,当这个触发条件满足时可以执行动作。
image5d2454f71bb7b2ba.png

commands(命令)

imageba834d01164dd5ab.png

properties

init程序在运行时会更新属性系统的一些属性,提供程序内部正在执行的信息.
image620ed0de50abd4ae.png

import类型

import 类型表示包含了另外一些 section,在解析完 init.rc 后会继续调用 init_parse_config_file 来解析引入的 .rc 文件。(最新的android11不一定是这个函数了)
eg:
比如我们在 init.sc8830.rc 的开始可以看到

import /init.usb.rc
import /init.trace.rc

表示在运行完本 rc 后还将继续运行 init.usb.rc 和 init.trace.rc。

2.2 调试注意事项

在默认情况下,通过init程序启动的程序的标准输出stdout和标准错误输出stderr会重定向到/dev/null.如:

service akmd /system/bin/logwrapper /sbin/akmd

为了更方便调试你的程序,你可以使用Android的log系统,标准输出和标准错误输出会重定义到Android的log系统中来.

参考文献:
init.rc介绍

独特见解