Android 系统启动
init 进程启动过程
init 进程是 Android 系统中用户空间的第一个进程,进程号为 1。init 进程由多个源文件共同组成,它们位于源码目录 system/core/init 中。
init 进程的入口函数
主要的几点:
- 在开始时创建和挂载启动所需的文件目录(系统运行时目录)
- 调用 property_init 函数对属性进行初始化
- 调用 start_property_init 函数启动属性服务
- 调用 signal_handler_init 函数用于设置子进程信号处理函数
此函数会接收系统在子进程暂停和终止时发出的 SIGCHLD 信号(其内部只处理进程终止的 SIGCHLD 信号),用以防止 init 进程的子进程成为僵尸进程。因为进程表是一项有限资源。 - 解析 init.rc 配置文件并启动 Zygote 进程
Zygote 进程启动过程
在 Android 系统中,DVM 和 ART、应用程序进程以及运行系统的关键服务的 SystemServer 进程都是由 Zygote 进程来创建的。
它通过 fock(复制进程)的形式来创建应用程序进程和 SystemServer 进程,由于 Zygote 进程在启动时会创建 DVM 或者 ART,因此通过 fock 而创建的两个进程可以在内部获取一个 DVM 或者 ART 的实例副本。
Zygote 启动脚本
在 init.rc 文件中采用了 Import 类型语句来引入 Zygote 启动脚本,这些启动脚本都是由 Android 初始化语言(Android Init Language)来编写的:
import /init.$(ro.zygote).rc
init.rc 不会直接引入一个固定的文件,会根据属性 ro.zygote 的内容来引入不同的文件。(4种取值)
Zygote 进程启动过程介绍
init 启动 Zygote 时主要是调用 app_main.cpp 的 main 函数中的 AppRuntime 的 start 方法来启动 Zygote 进程的。
Zygote 进程启动共做了如下几件事:
- 创建 AppRuntime 并调用其 start 方法,启动 Zygote 进程。
- 创建 Java 虚拟机并为它注册 JNI 方法。
- 通过 JNI 调用 ZygoteInit 的 main 函数进入 Zygote 的 Java 框架层。
- 通过 registerZygoteSocket 方法创建服务器端 Socket,并通过 runSelectLoop 方法等待 AMS 的请求来创建新的应用程序进程。
- 启动 SystemServer 进程。
SystemServer 处理过程
SystemServer 进程主要用于创建系统服务,AMS、WMS 和 PMS 都是由它来创建的。
SystemServer 进程被创建后,主要做了如下工作:
- 启动 Binder 线程池,这样就可以与其他进程进行通信。
- 创建 SystemServiceManager,其用于对系统的服务进行创建、启动和生命周期管理。
- 启动各种系统服务。
Launcher 启动过程
通俗来讲 Launcher 就是 Android 系统的桌面,它的作用主要是:
- 作为 Android 系统的启动器,用于启动应用程序。
- 作为 Android 系统的桌面,用于显示和管理应用程序的快捷图标或者其他桌面组件。
Android 系统启动流程
流程主要的几个部分:
- 启动电源以及系统启动
当电源按下时引导芯片代码从预定义的地方(固化在 ROM)开始执行。加载引导程序到 RAM 中,然后执行。 - 引导程序 BootLoader
是在 Android 操作系统开始运行前的一个小程序,它的主要作用是把系统 OS 拉起来并运行。 - Linux 内核启动
当内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。在内核完成系统设置后,它首先在系统文件中寻找 init.rc 文件,并启动 init 进程。 - init 进程启动
init 进程做的工作比较多,主要用来初始化和启动属性服务,也用来启动 Zygote(孵化器) 进程。 - Zygote 进程启动
创建 Java 虚拟机并为它注册 JNI 方法,创建服务器端 Socket,启动 SystemServer 进程。 - SystemServer 进程启动
启动 Binder 线程池和 SystemServiceManager,并且启动各种系统服务。 - Launcher 启动
被 SystemServer 进程启动的 AMS 会启动 Launcher,它启动后会将已安装应用的快捷图标显示到界面上。
备注
参考资料:
Android 进阶解密