android的首进程init

来源:互联网 发布:tcp协议栈源码 编辑:程序博客网 时间:2024/06/10 19:18

关于Init的理解

Initlinux系统的第一个用户进程,也是android的第一个用户进程。可以理解为是所有进程的父进程。Init是一个独立的执行程序,以main()函数开始,主要完成两个任务:配置文件解析和完成

(1)       进行准备工作:设置相关变量,设置子进程信息处理函数,创建相关文件和挂载设备文件以及重新设定std  I/O

(2)       解析配置文件:包含两个配置文件,系统和相关联硬件平台的配置文件。

(3)       完成action + 初始化和属性相关的资源:init-early; init; boot-early; boot这四个动作。在完成这些动作中一个最关键的就是完成zygote的创建工作。

(4)       进入一个新的阶段:init关注4件事情,主要是4个事件问题,接下来会进入到init的无限循环状态,调用poll()等待事情发生,同时当子进程死掉时,init要及时处理。

1.       解析配置文件的问题:完成这步是完成所有上层的基础工作。这个“文件”含义深刻。

总体来看是这个流程:解析函数parse_config()会找到配置文件的section,针对不同的section调用与之对应的解析函数完成parse任务。 

主要看解析init.rc

(1)       解析单位是section,同时注意的是在4个不同的action中对应不同的section。有boot-sectioninit-section等等。可能理解有问题,不同action时的section应该是有一些差异的。在这里说是zygote对应放在一个service section,我认为是,这个service section应该类似的是“公用的节点一样”,在不同action时会做个小的修饰等等。

2)解析section的本质是解析service,这个是一个service结构体定义完成。追踪函数是:parse_new_section()à parse_service()àparse_line_service()parse_service()这个只是一个解析service()的架子而已。

 

2.       准备工作已经完成,接下来就是zygote的启动:

zygote这个是init.rc中的。应该是这样的,走在bootsectionboot-section#class_start是一个COMMAND,执行函数为

Do_class_start(),它通过zygote serviceclassname找到zygote,然后对此进行执行工作。

3.       Zygote的启动是被放在另一个工作进程当中的,当然这个进程也是init的子进程。执行对应的zygote可执行文件,这个文件下的fork()execve()完成最终的启动创建工作。

4.       重启zygote:在initzygote中,要重启,先要杀掉之前的zygote,干掉zygote就干掉了zygote创建的所有子进程,这也是zygote干掉之后java崩溃的原因。重启的代码是在init.c中的无限循环下,for (; ; ;)Poll()返回后就进入下一个循环中。Zygote又回来了!

5.       Zygote service中的onrestart是另外的一些小问题。

 

(补充:(1)关于linux的处理:linux把所有的资源都按照文件处理,会在一个根目录下挂载不同的设备文件。

(2)       android是基于linux内核的,这个zygoteandroidandroid.mk文件把linux中的一个app_process换成这个名字而已,本质不变的。)

6.       init进程完成的另一项重要任务:属性服务的工作。

Android中的这个属性服务类似windows下的注册列表。这个属性服务中会记录一些系统或者应用程序的属性值,在重启等操作时,直接使用这样这个属性服务的内容便可以完成。

Init进程完成属性服务这项工作主要是分为两步:

(1)       分配内存块,因为客户进程也会这个内存中的信息,所以说应该这块内存是共享内存。Properyty_init()通过init_properyty_area()最终会使用init_workspace()获得内存。

(2)       Init进程进一步自动开启一个属性服务器,这个服务器实现跟客户的信息交互,客户通过这个服务器来设置属性。这个只针对属性的服务器中的内容包括有加载属性文件,目的是解析这些文件中的属性信息,然后把它们设置到属性空间。同时,这个服务器还要和客户端沟通,这里使用的是socket通信,所以必须创建socket

对于这个服务器的工作原理是,init首先自动启动该服务器,start_properyty_serive()函数完成启动,之后使用socket建立好连接就可以和客户端沟通了,当接收到客户端的请求,在判断请求合格后,用handle_properyty_set_fd()使用properyty_set()函数完成属性的设置任务。相对于客户端来说就简单些,利用socket和这个属性服务器建立好连接之后,socket发送请求,properyty_set(),可以将自己的需求告知服务器让它完成。

 

    至此,init进程的主要工作完成了。

 

原创粉丝点击