Android开机流程分析 -- init进程之配置文件解析

init.rc配置文件解析(system/core/rootdir/init.rc),分别讲解了Action、Service、PropertyService解析过程。
摘要由CSDN通过智能技术生成

继续上一节的分析步骤

(二)、init.rc配置文件解析(system/core/rootdir/init.rc

1、Android Init Language(Android初始化语言)

这里参照初始化语言的语法说明文档system/core/init/Readme.txt,介绍下Android初始化语言的语法知识。

(1)、基本约定

  • init由四类基本语句组成:Actions、Commands、Services、Options。
  • 所有类型的语句都是基于行的,每行都有若干个tokens组成,token之间以空格分开。如果一个token之间需要使用空格,则使用转义字符反斜线(‘\’)来转义,或者是使用双引号把整个token括起来。如果反斜线出现在行尾,表示下一行仍然是当前行。
  • 以“#”开始的行是注释行。
  • 动作(Actions)和服务(Services)表示一个新的段落(section)的开始,所有的指令(commands)和选项(options)归属于上方最近的一个段落。第一个段落之前的commands或options没有任何意义。
  • 动作(Actions)和服务(Services)拥有唯一的名字,如果出现重名,后面出现的将被作为错误忽略掉。

(2)、基本语法

Android初始化语言定义了六个基本概念:Section、Action、Service、Trigger、Command、Option;两个基本关键字:on、service、import;一些指令关键字。

  • Command:是最小的功能单元,表示一条Linux命令或一个函数的调用。
  • Trigger:表示一个触发条件,用来触发Action的执行,也可以表示一个Action的名称。
  • Option:是Service的修饰符,用来指定何时、如何启动Service程序
  • on:关键字on用来声明一个Action。
  • service:关键字service用来声明一个Service。关键字的定义在system/core/init/Keywords.h中声明。
  • Action:一个Action由关键字on声明、由Trigger触发的一组Command序列。
  • Service:每一个Service都是init进程的子进程,由关键字service、服务名、服务对应的命令的路径、命令的参数、Option组成,代表一些在初始化阶段启动的程序。
  • section:init.rc文件的基本组成单位就是section;每个Action或Service隐含表示一个section,每个section表示一个完整的功能。
  • import:代表一个section,表示引入另外一个.rc文件。

Action格式如下,其中on是声明Action的关键字,trigger是Action的触发条件,command是Action要执行的命令。
    on <trigger>
        <command>
        <command>
        <command>

举例说明:

on early-init
    # Set init and its forked children's oom_adj.
    write /proc/1/oom_score_adj -1000

    # Apply strict SELinux checking of PROT_EXEC on mmap/mprotect calls.
    write /sys/fs/selinux/checkreqprot 0

    # Set the security context for the init process.
    # This should occur before anything else (e.g. ueventd) is started.
    setcon u:r:init:s0

    # Set the security context of /adb_keys if present.
    restorecon /adb_keys

    start ueventd

    # create mountpoints
    mkdir /mnt 0775 root system

由这个Action表示的section是一个整体,因此组成Action的command是一起执行的。那么在什么时候执行呢?是有init.c的main函数决定的,main函数会在某个时刻调用action_for_each_trigger("early-init", action_add_queue_tail)函数,这样就会把这个Action里的所有命令加入到一个执行队列中,在某个时候会顺序执行队列了的命令。

Service格式如下,其中service是声明Service的关键字,name是Service的名字,pathname是Service所要执行的命令的路径,option是服务的启动配置参数。

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

举例说明:

service bootanim /system/bin/bootanimation

    user graphics

    group graphics

    disabled

    oneshot   # oneshot表示一个option

这里是一个Service表示的section,bootanim是服务名,/system/bin.bootanimation是bootanim服务执行的命令路径,oneshot表示这个服务只执行一次,如果没有该option,表示这个服务会一直存在,如果这个服务被杀死,则会重新启动。

import也表示一个section,import表示引入另外一个.rc文件。相当于包含另外一些section,在解析完init.rc后继续调用init_parse_config_file函数来解析引入的.rc文件。例如:

import /init.${ro.hardware}.rc

import /init.${ro.zygote}.rc

2、init.rc内容

(1)、init启动ServiceManager进程,这个进程主要负责系统服务的注册管理,包括“java系统服务”,“本地系统服务”。

serviceservicemanager/system/bin/servicemanager
    class core      #class关键字声明的Option,该Service属于core类别
    user system # user关键字声明的Option,该Service属于system用户
    group system 

    critical          #critical关键字声明的Option,该Service在4分钟内重启4次,将导致系统重启进入recovery模式  
    onrestart restart healthd    #onrestart关键字声明的Option,指定该Service重启后要执行的Command,restart zygote 是一个Command,restart对应的处理函数是do_restart
    onrestart restart zygote
    onrestart restart media
    onrestart restart surfaceflinger
    onrestart restart drm

(2)、init启动Media Server进程,这个进程负责启动C/C++的“本地系统服务”。

service media /system/bin/mediaserver
    class main
    user media
    group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm
    ioprio rt 4   #设置io优先级

(3)、init启动Zygote进程,这个进程启动SystemServer进程,从而启动“java系统服务”,包括PowerManagerService,SensorService等。

自从Android5.0开始创建zygote进程脚本是在Init.zygote**.rc里的(import /init.${ro.zygote}.rc),这是因为Android L支持64为的app,所以又起了一个Zygote64来专门负责64为APK的孵化。

init.rc对Zygote服务的section声明是在Init.zygote32.rc或Init.zygote64.rc或Init.zygote32_64.rc或Init.zygote64_32.rc中进行的(system/core/rootdir/),64位的芯片通常会使用system/core/rootdir/init.zygote64_32.rc

servicezygote/system/bin/app_process64-Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd

servicezygote_secondary/system/bin/app_process32-Xzygote /system/bin --zygote --socket-name=zygote_secondary
class main
socket zygote_secondary stream 660 root system
onrestart restart zygote

启动zygote进程时,传递参数-Xzygote /system/bin --zygote --start-system-server --socket-name=zygote。

3、init解析过程

在init.c的main函数中调用 init_parse_config_file("/init.rc"),表示开始解析init.rc配置文件,该函数位于system/core/init/Init_parser.c中

int init_parse_config_file(const char *fn)
{
    char *data;

   /* 调用open、read、malloc读取配置文件init.rc的内容到buffer,并配合struct stat记录文件状态,主要记录的是文件大小,保存到read_file的第二个参数,这里传入0,表示不带回文件大小。 */
    data = read_file(fn, 0);
    if (!data) return -1;

    parse_config(fn, data); /* 开始解析 init.rc */
    DUMP();   /* DUMP()位于/system/core/init/parser.c中,用于输出service_list和action_list中存储的Service和Action。调试的时候很大,默认是关闭的。 */
    return 0;
}

读取完配置文件的内容后,将调用parse_config进行解析。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值