Android启动之配置文件分析

Android启动之配置文件分析


本篇主要包括如下内容:

init.rc语法介绍

补充说明


一、init.rc语法介绍

1,init.rc是一个可配置的初始化文件,通常定制厂商可以配置额外的初始化配置,init.%PRODUCT%.rc

2,init.rc是在$GINGERBREAD/system/core/init/init.c中读取的,它基于“行”,包含一些用空格隔开的关键字(它属于特殊字符)

3,如果关键字中有空格,处理方法类似于C语言,使用/表示转义,使用“”防止关键字被断开,另外注意/在末尾表示换行

4,#开头的表示注释

5,init.rc包含4种状态类别:Actions/Commands/Services/Options

6,当声明一个service或者action的时候,它将隐式声明一个section,它之后跟随的command或者option都将属于这个section

7,action和service不能重名,否则忽略为error

8,actions就是在某种条件下触发一系列的命令,通常有一个trigger,形式如:

on <trigger>
     <command>
     <command>

9,service结构如下:
service <name> <pathname> [ <argument> ]*
     <option>
     <option>

10,option是service的修饰词,主要包括:

critical :表示如果服务在4分钟内退出超过4次,则系统重启到recovery mode

disabled :表示服务不会自动启动,需要显示调用服务名来启动

setEnv <name> <value> :设置环境变量<name>为某个值<value>

socket <name> <type> <permission> [<user> [<group>]] :开启一个unix域的socket,名字为/dev/socket/<name> , fd值传给启动它的进程。<type>只能是dgram,stream 或 seqpacket,而<user>和<group>默认为0

user <username> :表示将用户切换为<username>, 默认情况下用户都是root。

group <groupname> :表示将组切换为<groupname>

oneshot :表示这个service只启动一次

class <name> :指定一个要启动的类,这个类中如果有多个service,将会被同时启动。默认的class将会是“default”

onrestart :当此服务重启时,执行某些命令
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

11,trigger主要包括:

boot :当/init.conf加载完毕时

<name>=<value> :当<name>被设置为<value>时

device-added-<path> :设备<path>被添加时

device-removed-<path> :设备<path>被移除时

service-exited-<name> :服务<name>退出时
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

12,命令主要包括:
  

exec <path> [ <argument> ]* :Fork并执行一个<path>指定的程序。这条命令将阻塞直到该程序启动完成,因此它有可能造成init程序在某个点不停的等待。

export <name> <value> :设置一个全局变量

ifup <interface> :使网络接口<interface>成功连接

import <filename> :引入另一个配置文件

hostname <name> :设置主机名<name>

chdir <directory> :切换工作目录

chmod <octal-mode> <path> :设置访问权限

chown <owner> <group> <path> :设置用户和组
 
chroot <directory> :设置根目录位置

class_start <serviceclass> :启动<serviceclass>类名指定的所有相关服务(如果它们不在运行状态的话)

class_stop <serviceclass> :停止类中的<serviceclass>指定的服务(如果它们当前正在运行状态)

domainname <name> :设置域名

insmod <path> :安装模块

mkdir <path> [mode] [owner] [group] :创建一个目录,并可以指定权限,用户和组

mount <type> <device> <dir> [ <mountoption> ]* :尝试在指定路径下挂载一个设备,<mountoption> 包括"ro", "rw", "remount", "noatime"

setprop <name> <value> :设置系统属性

setrlimit <resource> <cur> <max> :设置资源访问权限

start <service> :开启服务(如果它没有处于运行状态的话)

stop <service> :停止服务(如果它当前正在运行的话)

symlink <target> <path> :创建一个<path>路径的链接,目标为<target>

sysclktz <mins_west_of_gmt> :设置基准时间

trigger <event> :触发一个事件

write <path> <string> [ <string> ]* :向<path>路径的文件写入多个<string>
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

二、init.rc补充

1,init.rc位于/system/core/rootdir/init.rc,这里会导入各个厂商的定制.rc文件(一般位于device目录下),如下所示。

import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /init.usb.configfs.rc
import /init.${ro.zygote}.rc
import /init.trace.rc
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

2,init进程会解析init.rc文件,如下所示。

int main(int argc, char** argv) {
    if (!strcmp(basename(argv[0]), "ueventd")) {
        return ueventd_main(argc, argv);
    }

    ...
  
    init_parse_config_file("/init.rc");

    action_for_each_trigger("early-init", action_add_queue_tail);

    ...
    action_for_each_trigger("init", action_add_queue_tail);

    queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");

    char bootmode[PROP_VALUE_MAX];
    if (property_get("ro.bootmode", bootmode) > 0 && strcmp(bootmode, "charger") == 0) {
        action_for_each_trigger("charger", action_add_queue_tail);
    } else {
        action_for_each_trigger("late-init", action_add_queue_tail);
    }

    queue_builtin_action(queue_property_triggers_action, "queue_property_triggers");

    while (true) {
       ...
    }
    return 0;
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

请注意上述代码中几个trigger的触发顺序:early-init --> init --> late-init,值得注意的是,late-init会继续触发trigger,如下所示。

on late-init
    trigger early-fs    //挂fstab.freescale里面的
    trigger fs       //挂fstab.freescale里面的
    trigger post-fs     //创建一堆的目录和数据

    # Load properties from /system/ + /factory after fs mount. Place
    # this in another action so that the load will be scheduled after the prior
    # issued fs triggers have completed.
    trigger load_system_props_action    //加载系统属性

    # Now we can mount /data. File encryption requires keymaster to decrypt
    # /data, which in turn can only be loaded when system properties are present
    trigger post-fs-data                 //创建data下面的目录
    trigger load_persist_props_action    //加载永久属性

    # Remove a file to wake up anything waiting for firmware.
    trigger firmware_mounts_complete

    trigger early-boot
    trigger boot    //启动boot
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

3,boot 中会启动core服务,如下所示。

on boot
    ...
    chown root system /sys/module/lowmemorykiller/parameters/adj
    chmod 0664 /sys/module/lowmemorykiller/parameters/adj
    chown root system /sys/module/lowmemorykiller/parameters/minfree
    chmod 0664 /sys/module/lowmemorykiller/parameters/minfree   
    ...    
    class_start core   //启动所有class标记为core的服务
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

4,关键字class说明

基本的服务类型(class)包括三种:core(最重要的)、main(次级重要的)、late_start(不那么重要的)。这三类服务分别通过class_start, class_reset, class_stop来对统一类的服务进行统一的操作。相同类别的服务,基本上是同时启动,相互之间的延时很小。

对/system/core/rootdir/init.rc中的class core进行全局搜索,列出部分结果如下:

ueventd /sbin/ueventd
logd /system/bin/logd
healthd /sbin/healthd
console /system/bin/sh
adbd /sbin/adbd
servicemanager /system/bin/servicemanager
vold /system/bin/vold
surfaceflinger /system/bin/surfaceflinger
bootanim /system/bin/bootanimation

对/system/core/rootdir/init.rc中的class main进行全局搜索,列出部分结果如下:

netd /system/bin/netd
debuggerd /system/bin/debuggerd
debuggerd64 /system/bin/debuggerd64
ril-daemon /system/bin/rild
surfaceflinger /system/bin/surfaceflinger
media /system/bin/mediaserver
bootanim /system/bin/bootanimation
installd /system/bin/installd
sshd /system/bin/start-ssh
zygote /system/bin/app_process

至此,init.rc语法已简单介绍完毕,细节需要去查看原始init.rc文件并结合解析器代码。

参考:

https://www.cnblogs.com/maogefff/p/7966799.html

https://www.cnblogs.com/senior-engineer/p/4848872.html

猜你喜欢

转载自blog.csdn.net/mediatec/article/details/88045507