Android内核开发:图解Android系统的启动过程
atmu
9年前
<p>学习任何软硬件系统,研究系统启动过程都是一种非常有效地起步手段,搞Android内核开发也不例外。网上有很多文章对Android启动相关代码进行分析和走读,大家可以先搜索阅读一下,我个人更喜欢更加直观的方式去理解未知的东西,包括图、表、系统输出的log信息等等,因此,本文准备通过一些流程图和log信息,来探索一下Android的启动过程。</p> <p>首先,给出一张图,图片来自<a href="/misc/goto?guid=4959673000442785485" title="">这里</a>,我觉得它画得很好,就引用过来了,帮助大家理解和分析。</p> <p> </p> <p><a href="https://simg.open-open.com/show/a36acda16ab32164fd6ab74bbd9290c8.jpg"><img alt="Android内核开发:图解Android系统的启动过程" src="https://simg.open-open.com/show/a36acda16ab32164fd6ab74bbd9290c8.jpg" width="515" height="730"></a></p> <p>第一阶段:Android设备上电后,首先会从处理器片上ROM的启动引导代码开始执行,片上ROM会寻找Bootloader代码,并加载到内存。(这一步由“芯片厂商”负责设计和实现)</p> <p>第二阶段:Bootloader开始执行,首先负责完成硬件的初始化,然后找到Linux内核代码,并加载到内存。(这一步由“设备厂商”负责设计和实现)</p> <p>第三阶段:Linux内核开始启动,初始化各种软硬件环境,加载驱动程序,挂载根文件系统,并执行init程序,由此开启Android的世界。(这一步则是Android内核开发过程中需要涉及的地方)</p> <p>Android系统以及各大Linux的发行版,他们的Linux内核部分启动过程都是差不多的,他们之间最大的区别就在于init程序的不同,因为init程序决定了系统在启动过程中,究竟会启动哪些守护进程和服务,以及呈现出怎样的一个用户UI界面。</p> <p>因此,init程序是分析Android启动过程中最核心的程序。</p> <p>对应的代码位于:system/core/init/init.c,工作内容如图所示(图片来自《Embedded Android》这本书):</p> <p> </p> <p><a href="https://simg.open-open.com/show/bd55485db536831d2390e80d93542b6e.jpg"><img alt="Android内核开发:图解Android系统的启动过程" src="https://simg.open-open.com/show/bd55485db536831d2390e80d93542b6e.jpg" width="566" height="645"></a></p> <p> </p> <p><strong>init程序最核心的工作主要有3点:</strong></p> <p> </p> <p>(1) 创建和挂载一些系统目录/设备节点,设置权限,如:/dev, /proc, and /sys</p> <p> </p> <p>(2) 解析 init.rc 和 init.<hardware>.rc,并启动属性服务,以及一系列的服务和进程。</p> <p> </p> <p>(3) 显示boot logo,默认是“Android”字样</p> <p> </p> <p>其中,最重要的步骤是第二步,一系列的Android服务在这时被启动起来,其实Android系统的启动最重要的过程也就是各个系统服务的启动,因为系统所有的功能都是依赖这些服务来完成的,比如启动应用程序,拨打电话,使用WIFI或者蓝牙,播放音视频等等,只要这些服务都能正常地启动起来并且正常工作,整个Android系统也就完成了自己的启动。</p> <p> </p> <p>这些服务包含2部分,一部分是本地服务,另一部分是Android服务,所有的这些服务都会向ServiceManager进程注册,由它统一管理,这些服务的启动过程介绍如下:</p> <p> </p> <h2><strong>(1)本地服务</strong></h2> <p> </p> <p>本地服务是指运行在C++层的系统守护进程,一部分本地服务是init进程直接启动的,它们定义在init.rc脚本和init.<hardware>.rc中,如 ueventd、servicemanager、debuggerd、rild、mediaserver等。还有一部分本地服务,是由这些本地服务进一步创建的,如mediaserver服务会启动AudioFlinger, MediaPlayerService, 以及 CameraService 等本地服务。</p> <p> </p> <p>我们可以通过查看init.rc和init.<hardware>.rc文件找出具体有哪些本地服务被init进程直接启动了,这些文件的位置:system/core/rootdir/</p> <p> </p> <p>注意,每一个由init直接启动的本地服务都是一个独立的Linux进程,在系统启动以后,我们通过adb shell命令进入手机后,输入top命令就可以查看到这些本地进程的存在:</p> <p> </p> <p><a href="https://simg.open-open.com/show/805f90500f727bbbcf16d3ac0657325a.jpg"><img alt="Android内核开发:图解Android系统的启动过程" src="https://simg.open-open.com/show/805f90500f727bbbcf16d3ac0657325a.jpg" width="728" height="709"></a></p> <p> </p> <h2><strong>(2)Android服务</strong></h2> <p> </p> <p>Android服务是指运行在Dalvik虚拟机进程中的服务,这些服务的创建过程描述如下:</p> <p> </p> <p>init进程会执行app_process程序,创建Zygote进程,它是Android系统最重要的进程,所有后续的Android应用程序都是由它fork出来的。</p> <p> </p> <p>Zygote进程会首先fork出"SystemServer"进程,"SystemServer"进程的全部任务就是将所有的Android核心服务启动起来,这些服务包括:</p> <p> </p> <p><a href="https://simg.open-open.com/show/f454721a71131e3cff38b10bc59f3d69.jpg"><img alt="Android内核开发:图解Android系统的启动过程" src="https://simg.open-open.com/show/f454721a71131e3cff38b10bc59f3d69.jpg" width="727" height="866"></a></p> <p> </p> <p>当所有的服务都启动完毕后,SystemServer会打印出“Making services ready”,然后通过ActivityManager启动Home界面,并发送“ACTION_BOOT_COMPLETED”广播消息。</p> <p> </p> <p>注意,这些Android服务并没有各种运行在独立的进程中,它们由SystemServer以线程的方式创建,所以都运行在同一个进程中,即SystemServer进程中。</p> <p> </p> <h2><strong>(3) 小结</strong></h2> <p> </p> <p>上面的几张图我总觉得还不够尽兴,因此文章最后,再给出一张图帮助大家加深一下理解,这幅图来自《Improving the Boot Time of the Android OS》这篇论文。</p> <p> </p> <p><a href="https://simg.open-open.com/show/fbe5ff0623b4a71184f35c7e9464c889.jpg"><img alt="Android内核开发:图解Android系统的启动过程" src="https://simg.open-open.com/show/fbe5ff0623b4a71184f35c7e9464c889.jpg" width="563" height="603"></a></p> <p>来自:http://ticktick.blog.51cto.com/823160/1659473</p>