鸟人的Android揭秘(14)——Init进程源代码分析(五)
前一篇主要讲解了init进程如何创建套接字以处理子进程终止,接下来我们继续分析init进程启动属性服务,以及分析init.rc的过程。
前一篇主要讲解了init进程如何创建套接字以处理子进程终止,接下来我们继续分析init进程启动属性服务,以及分析init.rc的过程。
Android系统的文件节点都使用SELinux管理权限,前面介绍的init进程第一阶段初始化创建的文件节点,以及属性初始化过程创建的文件节点,是在加载sepolicy之前已经被创建了,在加载完sepolicy之后,需要重新设置相关的属性。代码3-13所示是根据file_contexts[1]文件的内容设置相应文件节点的上下文。
前文已经介绍完init进程第一阶段的初始化,接下来我们开始讲解init进程第二阶段初始化过程,首先是属性的设置。
前面一节我们已经讲解了init进程对目录生成和挂载、日志初始化和设置,接下来init进程将初始化SELinux[1]并设置policy文件,如下面代码所示。若要详细了解SELinux的设计原理和工作机制,需要用一整本书来讲解,由于篇幅所限,在此我们不过多涉及这方面的内容。init进程运行在用户空间,主要涉及对SELinux的挂载和配置,下面我们把重点放在这个过程上。
本节开始依次分析init进程源代码中main()函数内的代码。受限于篇幅,我们无法将所有源代码一一列出讲解,这里分析主要流程和思路,希望读者能够参考init进程的实际代码,一起研究学习。
init进程分析init.rc启动脚本文件,并根据相关文件中包含的内容,执行相应的功能。另外,init进程提供属性服务,保存系统运行所需的环境变量。此外,其还负责监视子进程的运行,处理子进程的终止和重启。当应用程序访问设备驱动时,还会生成设备节点文件。接下来我们参考main()函数逐一分析代码。
众所周知,Linux中所有进程都是由init进程创建并运行起来的。首先Linux加载内核启动,然后在用户空间中启动init进程,之后init进程再依次启动系统运行的其它进程。在系统启动完成后,init进程会作为守护进程监视其它进程。若某个监视中的进程终结,进入僵死状态时,init进程就会释放进程所占用的系统资源。
在Android平台(以下称Android)中也存在init进程,除了提供以上常见的功能外,还提供几种额外的功能。
到目前为止,我们已经完整讲解完Android源代码的编译,以及基于Android Studio的开发环境搭建和调试,读者按照前文所述即可开始自己的Android探索之旅。
虽然Android Studio用来开发和调试Java代码非常方便,但对C/C++代码支持并不是很友好,C/C++开发利器Source Insight[1]也没有相应的Linux或Mac版本。为了方便查看Android源代码底层C/C++实现,我们再来讲解安装Sublime Text和CTags插件作为辅助工具。
前文已经讲解了Android源代码开发环境的搭建,以及如何使用模拟器加载源代码编译结果,但在开发过程中,无论是为了更地理解代码的运行机制,还是为了找出代码的Bug,都会涉及对代码的调试问题。接下来我们进一步说明,在Android Studio环境中,如何对Android源代码进行调试。
前文已经讲解了Android Studio的安装和配置,下面我们继续讲解如何把庞大的Android源代码加载到Android Studio中方便代码阅读和调试,以及如何启动模拟器加载Android源代码的编译结果,这些步骤都很重要,是后面讲解调试Android源代码的基础。
前面已经完整讲解了Android平台的构成,以及从Git服务器下载源代码并进行编译的内容。接下来讲解如何搭建Android SDK开发环境,包括Android Studio、Sublime、Android SDK等的下载与安装,这些都与Android应用程序开发与调试相关,可以极大的方便我们深入了解Android的源代码和运行机制。