【底层机制】【Android】Android 系统的启动流程

以下将从系统层面为你深入剖析Android系统的启动流程。这个过程非常复杂,但我们可以将其分解为几个清晰的阶段来理解。

Android启动流程的核心目标是:将系统从开机(Power On)引导至用户可以使用桌面(Launcher)并与其应用交互

整个流程可以概括为以下五个关键阶段,下图清晰地展示了其顺序与核心任务:

flowchart TD A[Boot ROM & Bootloader] --> B[Linux Kernel启动] B --> C[Init进程 & 服务启动] C --> D[Zygote进程初始化] D --> E[System Server进程启动] E --> F[Launcher启动]

下面我们来详细讲解每一个阶段。


阶段一:Boot ROM 和 Bootloader

当设备通电后,这是一个完全硬件初始化的阶段。

  1. Boot ROM (Bootloader Firmware):

    • 这是芯片内部固化的代码(固化在ROM中),无法修改。
    • 通电后,CPU会从预定义的固定地址开始执行指令,这个地址就是Boot ROM代码。
    • Boot ROM的职责是初始化最基本的硬件(如时钟、最小化的内存控制器),然后从引导媒介 (通常是eMMC或UFS存储芯片)上的特定分区加载Bootloader
  2. Bootloader:

    • 它是一个小程序,例如高通平台的Little Kernel (LK)或U-Boot。它的主要作用是一个"引导者"。
    • 核心职责 :
      • 初始化更多硬件:如内存、显示器、键盘等。
      • 设置安全环境:验证接下来要加载的软件(如内核)的完整性和真实性,确保系统未被篡改(例如,使用dm-verity)。
      • 加载并启动Linux Kernel :从存储的boot分区找到内核镜像,将其加载到内存中,然后跳转到内核的入口点执行。

专家提示:Bootloader通常是设备厂商(OEM)锁定的,不同厂商甚至不同型号设备的Bootloader都可能不同。解锁Bootloader是刷机的第一步。


阶段二:Linux Kernel 启动

现在,控制权从Bootloader移交给了Android系统的基石------Linux内核。

  1. 内核自解压与初始化:

    • 内核首先会解压自己(如果是压缩格式),然后设置系统环境。
    • 初始化核心子系统:如调度器(Scheduler)、内存管理(VM)、中断控制器(IRQ)。
    • 初始化驱动模型:建立设备模型总线。
  2. 驱动初始化:

    • 内核开始扫描并初始化所有已编译进内核或作为模块加载的设备驱动程序(如显示器、触摸屏、USB、Binder IPC等)。
    • 设备树(Device Tree):在嵌入式系统(如Android)中,硬件配置信息(内存地址、中断号等)通常通过一个叫做"设备树"的静态数据结构传递给内核,而不是像PC一样动态探测。
  3. 挂载根文件系统:

    • 内核会挂载初始root文件系统(通常是rootfs,一个在内存中的临时文件系统)。
    • 内核在根文件系统中寻找第一个用户空间进程。
  4. 启动init进程:

    • 内核启动完成后,会在根文件系统中找到并执行第一个用户空间进程------/init至此,Linux内核的引导工作完成,控制权交给Android用户空间。

阶段三:Init 进程与 ServiceManager

这是Android用户空间的起点,init进程的PID永远是1。

  1. Init 进程:

    • 它的源代码在system/core/init。它通过解析两个主要的配置文件来工作:
      • init.rc (主配置文件)
      • 设备厂商提供的init.{hardware}.rc (硬件特定配置)
    • 解析.rc文件 :这些文件使用一种特定的脚本语言,定义了ActionsServicesCommandsTriggers
  2. 启动核心原生服务:

    • Init进程会首先启动一些至关重要的、用C/C++编写的本地服务(Native Daemons),例如:
      • servicemanager:Binder IPC机制的守护进程,是所有Binder服务的大管家,负责服务的注册和查询。
      • hwservicemanager:为HIDL服务提供类似功能。
      • vndservicemanager:为Vendor进程间的Binder通信提供服务。
      • surfaceflinger:负责图形合成的核心服务。
      • healthd:电池状态守护进程。
  3. 启动Zygote:

    • init.rc文件中,有一个非常重要的service命令,它定义了如何启动Zygote进程。
    bash 复制代码
    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应用生态的"孵化器",它的设计极大地优化了应用启动速度。

  1. 启动Java虚拟机:

    • Zygote进程自己会首先启动一个Java虚拟机
    • 预加载 :在启动后,Zygote会预加载 所有Android应用可能需要的Java核心类(如android.*, java.*包)和资源。这是一个非常耗时的操作。
  2. 预加载资源与共享库:

    • 它还会预加载通用的资源文件(如framework-res.apk中的资源)和共享库。
    • 关键优势 :当一个新应用被Zygote"孵化"出来时(通过fork()系统调用),它会天然继承所有这些已经加载到内存中的类和资源。由于fork()是一个写时复制 的过程,这些内存页在子进程中是只读共享的,这避免了每个应用都重复加载,极大地节省了内存和启动时间
  3. 启动System Server:

    • Zygote在初始化完成后,会立即fork()出第一个子进程------System Server
  4. 监听Socket:

    • 之后,Zygote进程本身会进入一个循环,监听在init阶段创建的Socket,等待来自ActivityManagerService的请求,以便孵化新的应用进程。

阶段五:System Server 与 系统服务就绪

这是Android系统服务的核心,所有重要的系统服务都在这里启动。

  1. System Server 进程:

    • 这是一个运行在system_server进程中的Java代码,入口点通常是com.android.server.SystemServermain()方法。
  2. 启动Bootstrap、Core和Other服务:

    • 启动过程是分阶段的,以避免服务之间的循环依赖。
    • 引导服务 :最先启动的、最基础的服务。
      • ActivityManagerService (AMS):应用生命周期和任务栈的核心管理者。
      • PowerManagerService (PMS):电源管理。
      • PackageManagerService (PKMS):应用安装、卸载和权限管理。
    • 核心服务
      • WindowManagerService (WMS):窗口管理和屏幕绘制调度。
      • DisplayManagerService:显示设备管理。
    • 其他服务
      • InputManagerService:输入事件管理。
      • NotificationManagerService:通知管理。
      • ... 以及数十个其他服务。
  3. 系统服务就绪与启动Launcher:

    • 当所有关键系统服务启动并注册到ServiceManager后,SystemServer会调用ActivityManagerServicesystemReady()方法。
    • AMS在这个方法中会:
      • 发送系统广播ACTION_BOOT_COMPLETED,告知系统启动完成。
      • 启动桌面应用 :通过startHomeActivityLocked()方法,向Launcher应用(它的Intent Filter包含了CATEGORY_HOME)发送一个Intent,启动桌面。

总结

至此,用户看到了熟悉的桌面,Android启动流程全部完成。我们可以用一张更详细的流程图来回顾这个环环相扣的过程:

flowchart TD A[上电
Boot ROM] --> B[Bootloader
加载内核] B --> C[Linux Kernel
初始化驱动 挂载rootfs] C --> D[Init进程
PID=1] D -- 启动原生服务 --> E[ServiceManager
SurfaceFlinger等] D -- 启动Zygote --> F[Zygote进程
创建VM 预加载类资源] F -- fork --> G[System Server进程] G -- 启动 --> H[ActivityManagerService
PowerManagerService等] H -- 调用systemReady --> I[启动Launcher
发送BOOT_COMPLETED广播] I --> J[用户界面就绪] F -.->|通过Socket等待请求| H H -.->|请求Zygote fork新应用| F

理解这个完整的流程,对于处理系统启动性能优化、系统定制、以及解决一些深层次的系统问题(如开机卡顿、服务启动失败等)至关重要。

相关推荐
有位神秘人21 小时前
Android中Notification的使用详解
android·java·javascript
·云扬·21 小时前
MySQL Binlog落盘机制深度解析:性能与安全性的平衡艺术
android·mysql·adb
独自破碎E1 天前
【BISHI9】田忌赛马
android·java·开发语言
代码s贝多芬的音符1 天前
android 两个人脸对比 mlkit
android
darkb1rd1 天前
五、PHP类型转换与类型安全
android·安全·php
gjxDaniel1 天前
Kotlin编程语言入门与常见问题
android·开发语言·kotlin
csj501 天前
安卓基础之《(22)—高级控件(4)碎片Fragment》
android
峥嵘life1 天前
Android16 【CTS】CtsMediaCodecTestCases等一些列Media测试存在Failed项
android·linux·学习
stevenzqzq1 天前
Compose 中的状态可变性体系
android·compose
似霰1 天前
Linux timerfd 的基本使用
android·linux·c++