【底层机制】【Android】Android 系统的启动流程
以下将从系统层面为你深入剖析Android系统的启动流程。这个过程非常复杂,但我们可以将其分解为几个清晰的阶段来理解。
Android启动流程的核心目标是:将系统从开机(Power On)引导至用户可以使用桌面(Launcher)并与其应用交互。
整个流程可以概括为以下五个关键阶段,下图清晰地展示了其顺序与核心任务:
下面我们来详细讲解每一个阶段。
阶段一:Boot ROM 和 Bootloader
当设备通电后,这是一个完全硬件初始化的阶段。
-
Boot ROM (Bootloader Firmware):
- 这是芯片内部固化的代码(固化在ROM中),无法修改。
- 通电后,CPU会从预定义的固定地址开始执行指令,这个地址就是Boot ROM代码。
- Boot ROM的职责是初始化最基本的硬件(如时钟、最小化的内存控制器),然后从引导媒介(通常是eMMC或UFS存储芯片)上的特定分区加载Bootloader。
-
Bootloader:
- 它是一个小程序,例如高通平台的
Little Kernel (LK)或U-Boot。它的主要作用是一个“引导者”。 - 核心职责:
- 初始化更多硬件:如内存、显示器、键盘等。
- 设置安全环境:验证接下来要加载的软件(如内核)的完整性和真实性,确保系统未被篡改(例如,使用dm-verity)。
- 加载并启动Linux Kernel:从存储的
boot分区找到内核镜像,将其加载到内存中,然后跳转到内核的入口点执行。
- 它是一个小程序,例如高通平台的
专家提示:Bootloader通常是设备厂商(OEM)锁定的,不同厂商甚至不同型号设备的Bootloader都可能不同。解锁Bootloader是刷机的第一步。
阶段二:Linux Kernel 启动
现在,控制权从Bootloader移交给了Android系统的基石——Linux内核。
-
内核自解压与初始化:
- 内核首先会解压自己(如果是压缩格式),然后设置系统环境。
- 初始化核心子系统:如调度器(Scheduler)、内存管理(VM)、中断控制器(IRQ)。
- 初始化驱动模型:建立设备模型总线。
-
驱动初始化:
- 内核开始扫描并初始化所有已编译进内核或作为模块加载的设备驱动程序(如显示器、触摸屏、USB、Binder IPC等)。
- 设备树(Device Tree):在嵌入式系统(如Android)中,硬件配置信息(内存地址、中断号等)通常通过一个叫做“设备树”的静态数据结构传递给内核,而不是像PC一样动态探测。
-
挂载根文件系统:
- 内核会挂载初始
root文件系统(通常是rootfs,一个在内存中的临时文件系统)。 - 内核在根文件系统中寻找第一个用户空间进程。
- 内核会挂载初始
-
启动init进程:
- 内核启动完成后,会在根文件系统中找到并执行第一个用户空间进程——
/init。至此,Linux内核的引导工作完成,控制权交给Android用户空间。
- 内核启动完成后,会在根文件系统中找到并执行第一个用户空间进程——
阶段三:Init 进程与 ServiceManager
这是Android用户空间的起点,init进程的PID永远是1。
-
Init 进程:
- 它的源代码在
system/core/init。它通过解析两个主要的配置文件来工作:init.rc(主配置文件)- 设备厂商提供的
init.{hardware}.rc(硬件特定配置)
- 解析.rc文件:这些文件使用一种特定的脚本语言,定义了Actions、Services、Commands和Triggers。
- 它的源代码在
-
启动核心原生服务:
- Init进程会首先启动一些至关重要的、用C/C++编写的本地服务(Native Daemons),例如:
- servicemanager:Binder IPC机制的守护进程,是所有Binder服务的大管家,负责服务的注册和查询。
- hwservicemanager:为HIDL服务提供类似功能。
- vndservicemanager:为Vendor进程间的Binder通信提供服务。
- surfaceflinger:负责图形合成的核心服务。
- healthd:电池状态守护进程。
- Init进程会首先启动一些至关重要的、用C/C++编写的本地服务(Native Daemons),例如:
-
启动Zygote:
- 在
init.rc文件中,有一个非常重要的service命令,它定义了如何启动Zygote进程。 -
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main socket zygote stream 660 root system ... - 这行配置告诉init进程:创建一个名为
zygote的服务,执行/system/bin/app_process这个二进制文件,并传入参数。同时,创建一个名为zygote的Socket。
- 在
阶段四:Zygote 进程
Zygote是整个Android应用生态的“孵化器”,它的设计极大地优化了应用启动速度。
-
启动Java虚拟机:
- Zygote进程自己会首先启动一个Java虚拟机。
- 预加载:在启动后,Zygote会预加载所有Android应用可能需要的Java核心类(如
android.*,java.*包)和资源。这是一个非常耗时的操作。
-
预加载资源与共享库:
- 它还会预加载通用的资源文件(如
framework-res.apk中的资源)和共享库。 - 关键优势:当一个新应用被Zygote“孵化”出来时(通过
fork()系统调用),它会天然继承所有这些已经加载到内存中的类和资源。由于fork()是一个写时复制的过程,这些内存页在子进程中是只读共享的,这避免了每个应用都重复加载,极大地节省了内存和启动时间。
- 它还会预加载通用的资源文件(如
-
启动System Server:
- Zygote在初始化完成后,会立即
fork()出第一个子进程——System Server。
- Zygote在初始化完成后,会立即
-
监听Socket:
- 之后,Zygote进程本身会进入一个循环,监听在
init阶段创建的Socket,等待来自ActivityManagerService的请求,以便孵化新的应用进程。
- 之后,Zygote进程本身会进入一个循环,监听在
阶段五:System Server 与 系统服务就绪
这是Android系统服务的核心,所有重要的系统服务都在这里启动。
-
System Server 进程:
- 这是一个运行在
system_server进程中的Java代码,入口点通常是com.android.server.SystemServer的main()方法。
- 这是一个运行在
-
启动Bootstrap、Core和Other服务:
- 启动过程是分阶段的,以避免服务之间的循环依赖。
- 引导服务:最先启动的、最基础的服务。
- ActivityManagerService (AMS):应用生命周期和任务栈的核心管理者。
- PowerManagerService (PMS):电源管理。
- PackageManagerService (PKMS):应用安装、卸载和权限管理。
- 核心服务:
- WindowManagerService (WMS):窗口管理和屏幕绘制调度。
- DisplayManagerService:显示设备管理。
- 其他服务:
- InputManagerService:输入事件管理。
- NotificationManagerService:通知管理。
- … 以及数十个其他服务。
-
系统服务就绪与启动Launcher:
- 当所有关键系统服务启动并注册到ServiceManager后,
SystemServer会调用ActivityManagerService的systemReady()方法。 - AMS在这个方法中会:
- 发送系统广播
ACTION_BOOT_COMPLETED,告知系统启动完成。 - 启动桌面应用:通过
startHomeActivityLocked()方法,向Launcher应用(它的Intent Filter包含了CATEGORY_HOME)发送一个Intent,启动桌面。
- 发送系统广播
- 当所有关键系统服务启动并注册到ServiceManager后,
总结
至此,用户看到了熟悉的桌面,Android启动流程全部完成。我们可以用一张更详细的流程图来回顾这个环环相扣的过程:
理解这个完整的流程,对于处理系统启动性能优化、系统定制、以及解决一些深层次的系统问题(如开机卡顿、服务启动失败等)至关重要。
