(懒人近期想起我还有csdn好久没打理了。这个android init躺在我的草稿箱中快5年了。略微改改发出来吧)

RC文件格式

rc文件是linux中常见的启动载入阶段运行的文件。rc是run commands的缩写。基本上能够理解为在启动阶段运行的一些列命令。android init进程启动时,也会运行此启动脚本文件,init.rc。init.rc的写法稍有点复杂,具体可參考 /system/core/init下的readme文件。脚本基本组成是由四类,为:

  • commands: 命令
  • action:  动作
  • services: 服务
  • options:  选项

该语言的语法包含下列约定:

  • 全部类型的语句都是基于行(line-oriented)的,一个语句包括若干个tokens,token之间通过空格字符分隔。

    假设一个token中须要包括空格字符,则须要通过C语言风格的反斜线('\')来转义。或者使用双引號把整个token引起来。

    反斜线还能够出如今一行的末尾。表示下一行的内容仍然属于当前语句。

  • 以'#'開始的行是凝视行(凝视仅仅能是行的第一个非空字符,这个千万要注意)。

  • 动作(Actions)和服务(Services)语句隐含表示一个新的段落(section)的開始。

    全部的指令(commands)和选项(options)归属于上方近期的一个段落。在第一个段落之前的指令(commands)和选项(options)是无效的。

  • 动作(Actions)和服务(Services)拥有唯一性的名字。假设出现重名。那么后出现的定义将被作为错误忽略掉【眼下还是忽略,不是覆盖!

    】。

事实上。严格来说,应该就仅仅有两种类别Action和Service:

  • Action是由特定trigger下的一堆command组成
  • Service是由一堆options描写叙述的daemon服务组成

动作(Action)

动作(Action)是一个有名字的指令(commands)序列。每一个动作(Action)都定义一个触发条件(trigger)。用于指示什么时候运行这个动作。

在实际处理中。当与动作的触发器匹配的事件发生时。该动作下的命令,将被加入到一个即将被运行的队列的队尾(除非它已经在队列中)。

队列中的每个命令被依次取出运行。

一个动作定义的形式例如以下:

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

服务(Services)

服务是初始化程序须要启动的一些程序,初始化程序还有可能会在这些程序退出之后重新启动它们。Services take一个服务定义的形式例如以下:

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

选项(Options)

选项将影响控制初始化程序执行服务的时机和方法。可能的选项例如以下表(注意,options仅仅是作为服务的附属部分的)..

说明:

disabled

服务在启动所属的class的时候,不会自己主动随之启动,仅仅有明白指明要启动此服务时才会启动(通常每一个服务都会属于一个class中,由classkeyword描写叙述)

 

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

Create a unix domain socket named/dev/socket/<name> and pass its fd to the launched process. Valid<type> values includedgram andstream.user andgroup default to 0.

 

user <username>

在exec启动此服务之前,改变进程的user。默认user是root

 

group <groupname> [ <groupname> ]*

周期exec启动服务之前。改变此服务进程的group. 默认group是root。将服务增加特定的group,能够获取一些特定的权限。

 

capability [ <capability> ]+

Set linux capability before exec'ing this service

 

oneshot

服务仅仅运行一次。对于非daemon程序。必需要使用onshot模式。

 

class <name>

设定服务的class名字,全部的服务都必须设置一个,假设不设置。默认是属于default class的。同一个class中的服务。能够通过命令class_start统一启动。

触发器(Triggers)

触发器是一个字符串,用于匹配特定的事件。这些事件将触发触发器所属动作(Action)的运行。

指令(Commands)

支持哪些指令。各个android版本号不尽同样。详情可參考/system/core/init下的readme或最好看代码

属性(Properties)

初始化程序(Init)能够依据须要改动一些系统的属性。readme中说的三个:

init.action

Equal to the name of the action currently being executed or "" if none.

init.command

Equal to the command being executed or "" if none.

 

init.svc.<name>

State of a named service ("stopped", "running", or "restarting").

实际init进程仅仅看到更新 init.svc.<name>, 每一个服务都会创建一个这种property。能够通过 getprop | grep init.svc 看到每一个服务的状态,状态切换的时候,会同一时候更新。

void notify_service_state(const char *name, const char *state)
{
char pname[PROP_NAME_MAX];
int len = strlen(name);
if ((len + 10) > PROP_NAME_MAX)
return;
snprintf(pname, sizeof(pname), "init.svc.%s", name);
property_set(pname, state);
}

其它两个没意义,实际也没用,可能当初设计有吧,但最后也没用(comman/action都是开机时运行,且持续时间都非常短,没太大用处)。

init 的parser

Init的parser是比較简单的自己主动机,代码也不算复杂,主要parser的是三部分:

  1. service: 每一个service的描写叙述及属性,parser好了,放在service_list中,以便以后通过actions的命令启动。

  2. actions: parser每一个动作, on XXX及后继的command。就是一个action。这个parser好后。也是放在action_list中,以便在init中启动。
  3. import: init.rc 能够支持像c中的include一样,包括其它init.rc。这个支持比較简单,并非相当于在import位置插入被import的代码。而是在主init.rc都parser好后。再依次parser被包括的rc文件。

init.rc脚本命令的运行

脚本解析好后,会将各个Actions依照时间顺序,分别推到action_queue中,再一个一个运行。

actions依照trigger的时间顺序,依次运行的是。默认trigger的顺序例如以下:

 action_for_each_trigger("early-init", action_add_queue_tail);
action_for_each_trigger("init", action_add_queue_tail);
action_for_each_trigger("early-fs", action_add_queue_tail);
action_for_each_trigger("fs", action_add_queue_tail);
action_for_each_trigger("post-fs", action_add_queue_tail);
action_for_each_trigger("post-fs-data", action_add_queue_tail);
action_for_each_trigger("early-boot", action_add_queue_tail);
action_for_each_trigger("boot", action_add_queue_tail);

因此。各个命令须要特别注意处理好依赖。比方在init阶段。是不可能訪问data分区的。另外还要注意一下。 同一个阶段中,import的rc文件,是在后面一些运行的(依据import文件的parser顺序)。

service的启动时间。须要注意一下,也是通过action中的command运行的。 比方在on boot阶段:

 on boot
...
class_start core

这样。在boot阶段运行到这个命令时。全部属于core这一类的服务,都会被逐个启动。







android init进程分析 init脚本解析和处理的更多相关文章

  1. 构建根文件系统之init进程分析

    busybox是ls.cp等命令的集合. 执行ls时,实际上是执行了busybox ls 执行cp时,实际上是执行了busybox cp 分析init程序之前,再让我们回想一下我们的目标:u-boot ...

  2. android init进程分析 ueventd

    转自:http://blog.csdn.net/freshui/article/details/2132299 (懒人最近想起我还有csdn好久没打理了,这个Android init躺在我的草稿箱中快 ...

  3. Android 7.0 启动篇 — init原理(二)(转 Android 9.0 分析)

    ========================================================          ================================== ...

  4. 第一个用户进程 - Android 的 Init 进程

    本文尝试对着 <深入理解 Android 5.0 系统>来对 android 9.0 的启动代码进行分析,但是分析过程中发现自己缺乏操作系统方面的知识,以致于只能做一些简单分析.最近也买了 ...

  5. Android Init进程命令的执行和服务的启动

    这里开始分析init进程中配置文件的解析,在配置文件中的命令的执行和服务的启动. 首先init是一个可执行文件,它的对应的Makfile是init/Android.mk. Android.mk定义了i ...

  6. 第4阶段——制作根文件系统之分析init进程(2)

    本节目标: (1) 了解busybox(init进程和命令都放在busybox中) (2) 创建SI工程,分析busybox源码来知道init进程做了哪些事情 (3)  分析busybox中init进 ...

  7. Android4.4的init进程

    1背景 前些日子需要在科室内做关于Android系统启动流程的培训.为此,我在几年前的技术手记的基础上,重新改了一份培训文档.在重新整理文档期间,我也重读了一下Android 4.4的相关代码,发现还 ...

  8. Android2.2源码init机制分析

    1 源码分析必备知识 1.1 linux内核链表 Linux内核链表的核心思想是:在用户自定义的结构A中声明list_head类型的成员p,这样每个结构类型为A的变量a中,都拥有同样的成员p,如下: ...

  9. Linux下1号进程的前世(kernel_init)今生(init进程)----Linux进程的管理与调度(六)

    前面我们了解到了0号进程是系统所有进程的先祖, 它的进程描述符init_task是内核静态创建的, 而它在进行初始化的时候, 通过kernel_thread的方式创建了两个内核线程,分别是kernel ...

随机推荐

  1. 遗传奥秘的伟大揭秘者:J.Watson

    J.Watson的近照: 人们公认,揭秘生命体的遗传奥秘(DNA)是二十世纪最伟大的科技成果之中的一个,或许就是人类最伟大的科技进步(而不是"之中的一个"). 上世纪是人类做出伟大 ...

  2. 自醒的觉悟与力量——leo鉴书59

    30岁之后由于看得书多起来,阅读和写作也都有了自己的套路,与此相对的写书评之前须要看几遍书,然后我才干下笔的作者和作品越来越少了. 崔卫平是这种作者,而<正义之前>是我看了两遍才開始写评的 ...

  3. hive1.2伪分布mysql数据库配置具体解释

    hadoop2.6伪分布配置:http://blog.csdn.net/gamer_gyt/article/details/46793731 hive1.2  derby元数据库配置:http://b ...

  4. Bitcoin学习篇之---PPS和PPLNS挖矿模式介绍

    PPS和PPLNS挖矿模式介绍 比特币每10分钟产生一个区块,会有千万人竞争.而这个区块终于仅仅归1个人全部.其他人都颗粒无收. 你或许要挖5年才干获得一个区块. 组队挖矿就是.一旦队伍里不论什么人获 ...

  5. c1

    dmg和package是安装文件,dmg直接拖进应用程序中,pkg要进行安装. playfround是swift项目. --ios -----oc(面向对象的C) -----swift(oc的封装) ...

  6. Windows远程桌面和360

    Windows的远程桌面输错了一次密码, 然后就怎么都连接不上了, 查了半天发现 傻缺360会默认屏蔽Windows的远程桌面和数据库连接..... 大家没事都卸载了360吧

  7. 微信小程序 | 小程序的转发问题

    1.配置小程序页面静态转发信息 关于小程序转发问题,文档 在 page 页面填加了该监听函数,会在小程序右上角 ... 菜单中显示“转发”按钮: 监听函数需要 return {} 其中的内容配置转发信 ...

  8. Building Block[HDU2818]

    Building Block Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...

  9. navigate系列api

    wx.navigateTo  用于保留当前页面.跳转到应用内的某个页面,使用 wx.navigateBack可以返回到原页面.对于页面不是特别多的小程序,通常推荐使用 wx.navigateTo进行跳 ...

  10. string 去除空格

      /** * 去除空格 * @param {str} * @param {type} * type: 1-所有空格 2-前后空格 3-前空格 4-后空格 * @return {String} */ ...