前言
本文着重对 Android 系统启动流程做一个简析,旨在从宏观上了解 Android 启动流程,不涉及具体代码细节。
Android 系统启动流程
当我们按下手机电源键时,Android 系统就正式踏入了启动流程。那么,在我们按下电源键时,一直到显示 Launcher 界面时,Android 系统启动经历了那些流程呢?下面我们就具体来讲下大致的一些流程:
-
启动电源
按下电源键时,硬件电路连通,CPU 会从只读存储器(ROM)的某个具体地址开始加载引导程序(即 Bootloader 代码)到内存(RAM),然后执行 Bootloader。 -
引导程序:Bootloader
引导程序并不隶属于 Android 系统,它的作用是初始化硬件设备,加载内核文件等,为 Android 系统内核启动搭建好所需的环境(可以把 Bootloader 类比成 PC 的 BIOS)。
Bootloader 引导程序是 Android 系统开机运行的第一个程序,它是针对特定的主板与芯片的(与 CPU 及电路板的配置情况有关),因此,对于不同的设备制造商,它们的引导程序都是不同的。当前比较受欢迎的引导程序有 uboot,redboot 等等。
Bootloader 的引导程序一般分两个阶段执行:
-
Stage 1:基本的硬件初始化,目的是为 Stage 2 的执行以及随后的 kernel 的执行准备好一些基本的硬件环境。
Stage 1通常用汇编语言编写,以达到短小精悍的目的。 -
Stage 2:初始化 Flash 设备,设置网络、内存等等,将 kernel 映像和根文件系统映像从 Flash 上读到 RAM 空间中,加快内核启动速度。
Stage 2 的代码通常用 C 语言来实现,以便于实现更复杂的功能和取得更好的代码可读性和可移植性。
综上,引导程序的最终功能就是加载内核文件到内存中,然后启动内核。
-
Linux 内核启动
Linux 内核开始启动,初始化各种软硬件环境,加载驱动程序,挂载根文件系统……,最重要的是,内核启动完成后,它会在系统文件中寻找 ”init” 文件,然后启动 init 进程。到此,Android 新世界正式开启。 -
init 进程
init 进程是 Linux 系统中用户空间的第一个进程,进程号为1,我们可以说它是 root 进程或者所有进程的父进程。
init 进程有两个责任,一是挂载目录,比如/sys、/dev、/proc,二是运行 init.rc 脚本(init 进程在解析 init.rc 脚本时,会创建 Zygote 进程)。
注:Android 系统以及各大 Linux 的发行版,他们的 Linux 内核部分启动过程都是差不多的,他们之间最大的区别就在于 init 程序的不同,因为 init 程序决定了系统在启动过程中,究竟会启动哪些守护进程和服务,以及呈现出怎样的一个用户UI界面。
因此,init 程序是分析 Android 启动过程中最核心的程序。
-
Zygote 进程的创建
init 进程在解析 init.rc 脚本时,会创建 Zygote 进程,只有该进程才会建立起真正的 Android 运行空间,它是 Android 系统最重要的进程之一。后续 Android 中的应用进程都是由 Zygote 进程 Fork 出来的,因此,Zygote 是 Android 系统所有应用的父进程(即 Java 进程的鼻祖)。
注:Zygote 进程的出现是为了能更快的启动应用。因为在 Android 中,每个应用都有对应一个虚拟机实例(VM)为应用分配不同的内存地址。如果 Android 系统为每一个应用启动不同的 VM 实例,就会消耗大量的内存以及时间。因此,更好的办法应当是通过创建一个虚拟机进程,由该 VM 进程预加载以及初始化核心库类,然后,由该 VM 进程 Fork 出其他虚拟机进程,这样就能达到代码共享、低内存占用以及最小的启动时间,而这个 VM 进程就是 Zygote。
-
SystemServer 进程的创建
Zygote 进程做完初始化工作之后,会启动 SystemServer 进程,该进程承载着 framework 的核心服务(与 Zygote 进程一样,SystemServer 进程同样是 Android 系统中最重要的进程之一)。
SystemServer 的主要的作用是启动各种系统服务,比如 ActivityManagerService,PackageManagerService,WindowManagerService 以及硬件相关的 Service 等服务,我们平时熟知的各种系统服务其实都是在 SystemServer 进程中启动的(这些服务都运行在同一进程(即 SystemServer 进程)的不同线程中),而当我们的应用需要使用各种系统服务的时候其实也是通过与 SystemServer 进程通讯获取各种服务对象的句柄进而执行相应的操作的。 -
系统启动完成
一旦系统服务在内存中跑起来了,Android 就完成了启动过程。在这个时候 “ACTION_BOOT_COMPLETED” 开机启动广播就会发出去。
总结
我们知道,Android 系统是基于 Linux 系统的,因此,Android 系统的启动过程大致是与 Linux 系统一致的:
Bootloader 启动 Linux 内核程序;Linux 内核程序启动完成后,就会创建 init 进程(init 进程是 Linux 系统用户空间的第一个进程,是所有进程的父进程),init 进程分裂出更多名为 "daemons(守护进程)" 的底层的 Linux 进程, 诸如 android debug deamon, USB deamon 等,这些守护进程处理底层硬件相关的接口。随后,init 进程通过 init.rc 脚本文件启动 Zygote 进程(Zygote 进程是 Android 系统所有应用的父进程);Zygote 进程是 Android 系统中最重要的进程之一, Zygote 进程初始化了第一个 VM, 并且预加载了 framework 和众多 App 所需要的通用资源(res),然后它开启一个 Socket 来监听请求, 根据请求孵化出新的 VM 来管理新的 App 进程。一旦收到新的请求, Zygote 会基于自身预先加载的 VM 来孵化出一个新的 VM 创建一个新的进程;在 Zygote 进程启动之后,Zygote 会孵化出一个超级管理进程---SystemServer(该进程是 Android 系统中最重要的进程之一,上一个是 Zygote),SystemServer 会启动 Android 系统所有的核心服务(系统服务运行在 SystemServer 进程的不同线程中);到此,Android 系统启动完成,然后系统就会开始启动 Launcher 应用,我们就可以操作 App 了。
简单理解:
当我们按下手机电源键后,CPU 就会加载 Bootloader 引导程序;Bootloader会调起 Linux 内核程序;Linux 内核程序启动完成后,就会创建 init 进程;然后 init 进程通过 init.rc 脚本来启动 Zygote 进程;Zygote 进程又会创建 SystemServer 进程,由该进程去启动 Android 系统各种系统服务;到此,Android 系统已经启动完成。
最后,借助网上一张图来看下 Android 系统启动流程:
网友评论