ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Android系统启动流程深度解析:从Bootloader到Zygote的完整旅程

Android系统启动流程深度解析:从Bootloader到Zygote的完整旅程

引言

每次按下电源键,你的Android设备经历了什么?

从一片黑屏到看到开机Logo,从显示"Android"字样到进入锁屏界面,这短短几秒钟(或十几秒钟)背后,是一场精心编排的"启动大戏"。这场大戏有四幕:

第一幕: Bootloader → 加载并启动Kernel 第二幕: Kernel → 初始化硬件,启动init进程(PID 1) 第三幕: init → 挂载文件系统,启动核心服务 第四幕: Zygote → 准备应用运行环境

本文将带你完整走完这段旅程,重点聚焦第二幕到第三幕——从Kernel启动init,到init启动Zygote之前的所有准备工作。

📖系列前置阅读:建议先阅读第9-11篇(Binder IPC系列),理解进程间通信机制,这是理解系统服务启动的基础。


Android启动流程全景图

在深入细节之前,先建立整体认知:

图:Android 15系统启动的4个阶段,从Bootloader到Zygote的完整旅程,总耗时约6.5秒

本文聚焦范围:从Kernel启动init到Zygote启动之前,即上图中的第3步:init进程


Bootloader与Kernel启动(概览)

虽然不是本文重点,但理解这两个阶段有助于建立完整认知。

Bootloader阶段

Bootloader(引导加载程序)是设备上电后执行的第一段代码,由芯片厂商或设备厂商提供。

主要任务:

  1. 硬件初始化:

    • CPU频率和电压配置
    • 内存初始化(DDR)
    • 外设初始化(Flash/eMMC/UFS)
  2. 加载Kernel:

    • 从boot分区读取Kernel镜像(boot.img)
    • 解压Kernel到内存
    • 读取Device Tree Blob(DTB,设备树)
  3. 安全验证:

    • Verified Boot(Android Verified Boot):验证Kernel签名
    • 如果验证失败,显示警告或拒绝启动
  4. 启动Kernel:

    • 设置Kernel启动参数(cmdline)
    • 跳转到Kernel入口地址(通常是0x80008000)

常见Bootloader:

  • LK(Little Kernel):Qualcomm芯片常用
  • U-Boot:开源,通用性强
  • UEFI:PC和部分高端设备

关键日志(通过串口或fastboot查看):

[0.000000] Booting Linux on physical CPU 0x0 [0.000000] Linux version 5.15.123-android15 (build@hostname) ...

Kernel启动阶段

Linux Kernel负责硬件抽象和资源管理。

主要任务:

  1. 内存管理初始化:

    • 页表设置
    • 内存分配器(SLAB/SLUB)初始化
  2. 进程调度器初始化:

    • CFS调度器(Completely Fair Scheduler)
    • 实时调度器(RT)
  3. 驱动初始化:

    • 加载内置驱动(built-in)
    • 初始化设备树(Device Tree)中定义的硬件
  4. 文件系统初始化:

    • 挂载rootfs(根文件系统,通常是ramdisk)
    • 挂载/system、/vendor等分区(由init负责)
  5. 创建init进程:

    // kernel/init/main.c (简化)staticint__refkernel_init(void*unused){// ...if(!ramdisk_execute_command)ramdisk_execute_command="/init";returnrun_init_process(ramdisk_execute_command);}

关键Kernel参数(cmdline):

# 查看Kernel启动参数adb shellcat/proc/cmdline# 输出示例:# androidboot.hardware=qcom# androidboot.selinux=permissive # 或 enforcing# androidboot.verifiedbootstate=green# init=/system/bin/init

init进程:Android的"创世神"

init进程是Android用户态的第一个进程(PID 1),它的职责是创建整个用户态环境

init的三阶段启动

Android 15的init分为三个阶段,每个阶段有独立的入口函数:

main() → FirstStageMain() → SetupSelinux() → SecondStageMain() ↓ ↓ ↓ ↓ 入口 第一阶段 SELinux设置 第二阶段(核心)

让我们分析Android 15的源码:

阶段判断逻辑
// system/core/init/main.cpp (Android 15)intmain(intargc,char**argv){// 提升优先级(后续会恢复)setpriority(PRIO_PROCESS,0,-20);// 如果argv[0]是"ueventd",则以ueventd模式启动if(!strcmp(basename(argv[0]),"ueventd")){returnueventd_main(argc,argv);}if(argc>1){// 子上下文模式(用于隔离某些操作)if(!strcmp(argv[1],"subcontext")){returnSubcontextMain(argc,argv,&GetBuiltinFunctionMap());}// SELinux设置阶段if(!strcmp(argv[1],"selinux_setup")){returnSetupSelinux(argv);}// 第二阶段if(!strcmp(argv[1],"second_stage")){returnSecondStageMain(argc,argv);}}// 默认进入第一阶段returnFirstStageMain(argc,argv);}

关键设计:

  • init通过命令行参数判断当前应执行哪个阶段
  • 每个阶段完成后,会通过execv()重新执行自己,进入下一阶段
  • 这种设计允许在SELinux加载后"重启"进程,获得新的安全上下文

第一阶段:FirstStageMain()

核心目标:创建最基础的文件系统,加载SELinux策略。

// system/core/init/first_stage_init.cpp (简化)intFirstStageMain(intargc,char**argv){// ========== 1. 挂载基础文件系统 ==========CHECKCALL(mount("tmpfs","/dev","tmpfs",MS_NOSUID,"mode=0755"));CHECKCALL(mkdir("/dev/pts",0755));CHECKCALL(mkdir("/dev/socket",0755));CHECKCALL(mount("devpts","/dev/pts","devpts",0,NULL));// 挂载proc文件系统(读取内核信息)CHECKCALL(mount("proc","/proc","proc",0,"hidepid=2,gid=3009"));// 挂载sysfs(设备和驱动信息)CHECKCALL(mount("sysfs","/sys","sysfs",0,NULL));// 挂载selinuxfs(SELinux策略文件系统)CHECKCALL(mount("selinuxfs","/sys/fs/selinux","selinuxfs",0,NULL));// ========== 2. 创建必要的设备节点 ==========CHECK
返回列表