android init进程分析 init脚本解析和处理

学向勤中得,萤窗万卷书。这篇文章主要讲述android init进程分析 init脚本解析和处理相关的知识,希望能为你提供帮助。
  (懒人近期想起我还有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 的parserInit的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脚本解析和处理】
     







































    推荐阅读