【底层机制】【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

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

相关推荐
limuyang25 小时前
【http3/quic】cronet 已经原生集成在Android内啦!还不快来开开眼!
android·http·google
乌萨奇也要立志学C++5 小时前
【Linux】Ext系列文件系统 从磁盘结构到文件存储的原理剖析
android·linux·缓存·1024程序员节
宋发元6 小时前
IPhone 17 Pro Max拍摄专业画质视频教程
android·gradle·iphone
出门吃三碗饭8 小时前
如何在LLM大语言模型上微调来优化数学推理能力?
android·人工智能·语言模型
shaominjin1239 小时前
Android访问OTG文件全解析:从连接到操作的完整指南Android系统访问U盘的实现机制与操作指南
android
游戏开发爱好者812 小时前
HTTPS 内容抓取实战 能抓到什么、怎么抓、不可解密时如何定位(面向开发与 iOS 真机排查)
android·网络协议·ios·小程序·https·uni-app·iphone
Tom4i14 小时前
Android 系统的进程模型
android
介一安全14 小时前
【Frida Android】基础篇9:Java层Hook基础——Hook构造函数
android·网络安全·逆向·安全性测试·frida
杨筱毅14 小时前
【Android】Compose绘制系统 VS 传统View绘制系统
android