众所周知,Linux中全部进程都是由init进程建立并运行起来的。首先Linux加载内核启动,而后在用户空间中启动init进程,以后init进程再依次启动系统运行的其它进程。在系统启动完成后,init进程会做为守护进程监视其它进程。若某个监视中的进程终结,进入僵死状态时,init进程就会释放进程所占用的系统资源。html
在Android平台(如下称Android)中也存在init进程,除了提供以上常见的功能外,还提供几种额外的功能。android
在本章中,将讨论学习Android的init进程的功能,须要读者具备必定的Linux系统系统编程知识,若是您对Linux编程知识感到陌生,建议事先翻阅相关的书籍进行学习。编程
与Linux相似,Android内核启动后,也会在用户空间启动init进程,做为第一个用户级进程。函数
由上图内核启动过程能够看出,Android内核在启动过程当中,依次执行start_kernel()函数、rest_init()函数、kernel_init()函数和run_init_process()函数后,最后启动init进程。在rest_init()函数中即会建立出一个新进程用于运行init进程,以保证init进程是第一个用户级进程,其pid为1,在run_init_process()函数执行后,init进程即真正运行起来,如下代码是内核内部实现的init进程启动代码。学习
static int __ref kernel_init(void *unused) { ... if (execute_command) { ① ret = run_init_process(execute_command); if (!ret) return 0; panic("Requested init %s failed (error %d).", execute_command, ret); } if (!try_to_run_init_process("/sbin/init") || !try_to_run_init_process("/etc/init") || !try_to_run_init_process("/bin/init") || !try_to_run_init_process("/bin/sh")) return 0; panic("No working init found. Try passing init= option to kernel. " "See Linux Documentation/init.txt for guidance."); }
① kernerl_init()函数获取注册在execute_command中的进程文件路径,调用run_init_process()函数,执行do_execve()系统调用。do_execve()函数执行由参数传递过来的路径下的进程文件。注意,在设置内核启动选项时,应设置“init=/init”,以便正常运行init进程,由于在编译完Android后生成的根文件系统中,init进程文件位于系统最顶层目录中,以下图所示。ui
当文件系统的根目录中不存在init进程文件,或未指定启动选项“init=”时,内核会到/sbin、/etc、/bin目录下查找init文件。若是在这些目录仍未找到init文件,内核会引起Kernel Panic错误,终止执行init进程。rest
若上述kernel_init函数的代码执行成功,则init进程就正常启动。Android是个开源系统,代码均可如下载下来进一步查看,从而更好地把握某些进程的具体动做。从下一节开始,咱们将一块儿分析init进程的源代码[2],了解Android启动过程当中,init进程都作了哪些事情。code
[1] 此函数定义在kernel代码的init/main.c中。htm
[2] 该代码在kernel源代码的init目录下,kernel源代码的下载参考:http://source.android.com/source/building-kernels.html。进程