Android 启动流程详解
Android 的启动是一个
Android 的启动是一个从「硬件上电」到「用户看到桌面」的多阶段链式过程,可以概括为:
电源键按下
│
▼
┌──────────┐ ┌──────────┐ ┌────────────┐ ┌──────────┐ ┌─────────┐
│ Boot ROM │──▶│Bootloader│──▶│ Linux 内核 │──▶│ init │──▶│ Zygote │
│ (芯片固化)│ │(LK/ABL) │ │ (boot.img) │ │ (1/2阶段)│ │ │
└──────────┘ └──────────┘ └────────────┘ └──────────┘ └─────────┘
│
┌──────────────┐ ┌──────────────┐ │
│ Launcher 桌面 │◀──│ SystemServer │◀─────────────┘
└──────────────┘ └──────────────┘
下面按阶段逐一展开。
一、Boot ROM(芯片上电引导)
- 电源键按下后,芯片内部固化在 ROM 中的一段代码(Boot ROM,不可修改)首先执行。
- 它根据硬件引脚(Boot Pin)或 eMMC/UFS 的 boot 分区选择启动介质,加载 Bootloader 到 RAM 并把控制权交出去。
- 这一阶段与 SoC 厂商强相关(高通、MTK、三星等实现不同),出了问题基本只能走硬件级刷机/救砖。
二、Bootloader(以高通 ABL / MTK LK / U-Boot 为例)
Bootloader 通常有多级(如高通的 PBL → SBL/XBL → ABL),最终的主引导程序负责:
- 硬件最小初始化:时钟、内存控制器、串口、显示(开机 logo 就是这里画的)。
- 判断启动模式 :
- 正常模式 → 加载 boot 分区
recovery模式 → 加载 recovery 分区fastboot模式 → 进入刷机协议(长按音量键等触发)
- 验证镜像完整性(AVB, Android Verified Boot) :
- 校验 boot.img 的签名(vbmeta),防篡改;
- 配合 dm-verity 保证 system/vendor 分区在运行时只读且被验证;
- 验证失败时可能进入橙色/黄色启动警告状态或拒绝启动。
- 加载 boot.img :boot.img 由 kernel + ramdisk(initramfs)+ dtb(设备树) 组成,加载到 RAM 后跳转到内核入口。
A/B 无缝更新:A/B 设备有两套 slot(_a/_b),Bootloader 会尝试当前活跃 slot,多次启动失败可回滚到另一个 slot,这也是 Android 现代 OTA 的基础。
三、Linux 内核启动
- 内核自解压、架构初始化(ARM64 为例)、内存管理/调度/中断子系统初始化。
- 解析 DTB(设备树),识别板级硬件。
- 挂载 ramdisk(第一阶段 init 所在),初始化驱动(display、USB、存储、binder 等)。
- 启动内核线程(kthreadd、kworker 等),调用
start_kernel()的最后一步 →kernel_init()→ 执行 第一个用户空间进程:/init(PID=1)。
调试上,这阶段的信息看 dmesg / 串口 log。
四、init 进程(用户空间的起点)
init 是所有用户进程的祖先,分两个阶段(Android 9+ / Treble 之后尤其明显):
1. First Stage Init
- 挂载
/system、/vendor、/product等基础分区(含动态分区 device-mapper 映射,Android 10+); - 挂载
/dev(devtmpfs)、/proc、/sys; - SELinux 相关准备。
2. Second Stage Init
-
启动 属性服务(property service) :init 是属性的"守门人",所有
ro.*、sys.*等属性的读写经它仲裁; -
初始化 SELinux(加载 policy,进入 enforcing);
-
解析
*.rc启动脚本 (/system/etc/init/、/vendor/etc/init/等),这是 init 的"配置语言":service surfaceflinger /system/bin/surfaceflinger class core animation user system group graphics onrestart restart --only-if-running zygote on property:sys.boot_completed=1 class_start late_start -
启动 ueventd (设备节点管理)、logd(日志服务);
-
按 class 顺序拉起核心原生服务:
servicemanager(Binder 服务注册中心)、hwservicemanager(HIDL)、surfaceflinger、vold、netd、installd、healthd、storaged等。
init 通过 property trigger (如 on property:ro.crypto.state=*)和 class_start 机制编排整个原生服务栈的启动顺序。
五、Zygote 进程(Java 世界的奠基者)
init 根据 init.rc 中的 app_process 启动 Zygote (实际可执行文件是 app_process64):
- 创建 ART/Dalvik 虚拟机 :
AndroidRuntime::start()→ 启动 JVM; - 预加载公共资源 :预加载常用 Java 类(
preloadClasses,约上万个)、Framework 资源(preloadResources)、字体、共享库------这是"每个 App 进程不必重复加载"的关键优化; - 注册 Zygote Socket (
/dev/socket/zygote),进入runSelectLoop()等待 AMS 发来的 fork 请求; - fork SystemServer:Zygote 的第一个孩子就是 system_server。
Zygote 的存在意义:fork + copy-on-write 机制让所有 App 进程共享预加载的类和资源,大幅降低内存占用和启动耗时。Android 8.1+ 还有 USAP(Unspecialized App Process)池化预 fork 机制(默认关闭)。
六、SystemServer(系统服务的大脑)
system_server 是一个特殊的系统进程,里面跑着 100+ 个 Binder 服务,启动分三批:
| 阶段 | 代表服务 | 职责 |
|---|---|---|
| 引导服务 startBootstrapServices | AMS、PMS、PowerManagerService、DisplayManagerService、LightsService | 最基础、被其他服务依赖 |
| 核心服务 startCoreServices | BatteryService、UsageStatsService、WebViewUpdateService、CachedDeviceStateService | 核心但依赖少 |
| 其他服务 startOtherServices | WMS、InputManagerService、NetworkManager、AudioService、CameraService、AlarmManagerService、NotificationManager... | 其余全部 |
之后:
- 各服务依次
systemReady(),完成依赖闭合; - AMS 启动 SystemUI (状态栏、锁屏、导航)、Launcher(桌面 Activity);
- 当桌面第一帧上屏,系统发出广播
ACTION_BOOT_COMPLETED,设置sys.boot_completed=1,BOOTanim(开机动画)退出------开机流程结束。
七、App 进程的启动(顺带一提)
用户点开一个 App 时:
- Launcher → AMS(
startActivity); - AMS 发现目标进程不存在 → 通过 socket 通知 Zygote;
- Zygote fork 出新进程 → 创建 ART 实例(复用预加载资源);
- 反射调用
ActivityThread.main()→ 绑定 Application → 创建 Activity → 走完生命周期 → 上屏。
八、几个关键机制补充
Verified Boot / dm-verity:从 Bootloader 到运行时的完整信任链,防止系统分区被篡改,是 GMS 认证的硬性要求。
Treble(Android 8+) :把 vendor 实现与 framework 解耦(/vendor 独立、HIDL/AIDL 接口稳定),使系统升级不再依赖芯片厂商,直接改变了启动流程中的 HAL 加载方式。
APEX(Android 10+) :把 ART、Conscrypt 等模块做成类似 App 的可更新容器,在 init 早期由 apexd 挂载激活。
开机动画 :由 bootanim 服务播放(/system/media/bootanimation.zip),它结束是"启动完成"的视觉标志。
九、常见调试手段
| 手段 | 用途 |
|---|---|
dmesg / 串口 |
内核与 Bootloader 阶段问题 |
logcat -b all、logcat -s Zygote SystemServer |
init 之后的用户空间问题 |
getprop / setprop |
属性服务状态(如 sys.boot_completed) |
adb shell ps -A |
看进程拉起情况 |
| Bootchart / Perfetto / systrace | 量化各阶段耗时,做开机优化 |
adb wait-for-device; adb logcat 抓 Boot time 相关日志 |
测量冷启动耗时 |
一句话总结
Boot ROM 找 Bootloader → Bootloader 验证并加载内核 → 内核拉起 init → init 按 rc 脚本编排原生服务 → Zygote 预热虚拟机并 fork SystemServer → SystemServer 拉起 SystemUI 和 Launcher → 广播 BOOT_COMPLETED,开机完成。