本文结合资料和Android11源码,分析下设备从上电到用户界面 (HomeActivity) 的整个过程。如有遗漏或者错误之处,欢迎指出。
Android系统启动分为底层系统启动和应用系统启动两个阶段。
一、底层系统启动 (Linux内核与驱动层)
1.1 系统上电与Bootloader引导
当设备接通电源或复位后,CPU会从预先定义的复位向量地址(通常是ROM的零地址)开始执行指令。
关键过程如下:
- CPU复位:CPU上电复位,程序计数器(PC)指向启动ROM的起始地址。
- 执行固化启动代码:CPU读取并执行ROM中固化的初始引导代码。
- Bootloader的作用:Bootloader类似于PC的BIOS,其主要职责是:
- 初始化硬件设备(时钟、存储器、串口等)。
- 建立内存空间映射。
- 设置并准备启动参数。
- 加载并验证操作系统内核镜像,最终将控制权移交给内核。
- 加密与解锁:生产商通常对Bootloader加密以保障系统安全和完整性。解锁Bootloader将允许加载非官方系统,但会带来安全和稳定性风险。
1.2 Linux内核启动
Bootloader将内核镜像(在嵌入式系统中多为压缩镜像zImage)加载到指定内存地址,并跳转到该地址执行。
内核启动主要流程:
- 内核解压与自引导:如果是压缩镜像,先进行自解压。
- 核心初始化:架构相关代码初始化处理器、建立异常/中断向量表、初始化页表等。
- 通用内核初始化:
- 初始化系统核心调度器。
- 初始化内存管理。
- 初始化进程间通信(IPC)机制。
- 创建并初始化init进程的进程控制块(PID=1)。
- 初始化设备驱动、虚拟文件系统(VFS)等。
- 驱动初始化:内核通过静态编译或动态加载的方式初始化各类设备驱动。
- 挂载根文件系统:内核根据启动参数,将指定的存储分区(通常是只读的ramdisk或系统分区)挂载为根文件系统。
- 启动第一个用户空间进程:内核启动的最后一步是查找并执行根文件系统中的/init程序。若成功,内核启动完成,控制权移交给init进程。
二、应用系统启动
Linux内核启动后,Android特有的用户空间启动过程开始。init进程是这一切的发起者。
2.1 init进程与系统初始化
init是Android系统的第一个进程(PID=1),是所有后续进程的祖先进程。它在Android 11中的主要工作流程:
- 初始化Log系统与内核模块。
- 解析配置文件:
- init.rc:主配置文件,使用特定语法定义了启动阶段、动作、服务和命令。
- /system/etc/init/, /vendor/etc/init/, /odm/etc/init/:引入了分区的.rc配置文件,用于定义各子系统服务,实现了更好的模块化。
- 执行启动阶段:根据配置文件按顺序执行early-init、init、late-init、post-fs-data、late-fs等不同阶段的动作。
- 启动属性服务(Property Service):属性服务是Android中一个重要的键值对存储与通信系统。init进程作为属性服务的管理者,提供setprop/getprop功能,并监听/dev/__properties__目录。
- 进入事件循环:初始化完成后,init进程进入一个无限循环,负责:
- 响应属性改变事件。
- 管理和重启那些在.rc文件中定义为“critical”的关键服务。
- 处理子进程信号。
2.2 Zygote进程启动与Dalvik/ART预加载
init进程根据init.rc中zygote服务的定义启动Zygote。在Android 11中,通常启动的是 zygote64或 zygote32。
示例配置:
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
priority -20
user root
group root readproc
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
...
writepid /dev/cpuset/foreground/tasks
Zygote的核心作用:
- 创建Java虚拟机:Zygote进程启动时,会初始化一个全局的ART虚拟机实例(取代了早期的Dalvik)。
- 预加载类和资源:为了避免每个应用都重复加载,Zygote会预加载大量的Java核心类库(如framework.jar)、公共资源以及系统主题资源。
- 创建Socket监听:Zygote启动后,会打开一个名为“zygote”的Socket,用于监听来自ActivityManagerService(AMS)的请求,用来孵化新的应用进程。
- 孵化System Server:作为--start-system-server参数的结果,Zygote fork()出第一个子进程——System Server。这也是所有Java层系统服务的宿主进程。
2.3 System Server进程与核心服务启动
System Server运行在独立的进程中,承载了Android框架层绝大部分的系统服务。
启动流程:
- Zygote.forkSystemServer() 创建System Server进程。
- 在子进程中,执行com.android.server.SystemServer.main()。
- main()方法调用本地方法nativeZygoteInit()完成Binder线程池等的初始化。
- 调用run()方法(在SystemServer.java中),此方法是核心,它分阶段启动了数十个关键服务:
- 引导阶段 (Bootstrap):启动如ActivityManagerService、PowerManagerService等最基本的服务。
- 核心阶段 (Core):启动如PackageManagerService、DisplayManagerService等核心服务。
- 其他阶段 (Other):启动AlarmManagerService、InputManagerService、WindowManagerService等其它服务。这些服务大多数通过Binder IPC向应用提供服务。 注意:ActivityManagerService(AMS)在启动后,会等待系统进入“PHASE_ACTIVITY_MANAGER_READY”等状态,然后向Launcher应用(系统默认Home应用)发出启动指令。
2.4 启动HomeActivity(Launcher)
这是用户可见的启动流程终点。
- AMS发送启动意图:当系统服务基本就绪后,ActivityManagerService会广播CATEGORY_HOME类型的Intent。
- PackageManager解析:系统查询所有声明了CATEGORY_HOME的Activity。默认情况下,系统自带的Launcher应用(如Launcher3)会被选中。
- 启动Launcher进程:如果Launcher进程(通常是com.android.launcher3)尚未存在,AMS会通过Socket向Zygote发送请求。Zygote fork出一个新的ART虚拟机进程作为Launcher进程,并加载Launcher应用的APK。
- 显示主界面:Launcher进程启动后,创建并显示其HomeActivity,加载桌面布局、图标和小组件。用户至此看到熟悉的Android主界面,启动流程结束。
三、启动流程总结
综上所述,Android 11系统的启动流程概括如下:
关键源码路径 (AOSP 11)
system/core/init/init.cpp→ Init进程system/core/rootdir/init.rc→ 主启动脚本frameworks/base/core/java/com/android/internal/os/ZygoteInit.java→ Zygote入口frameworks/base/services/java/com/android/server/SystemServer.java→ 系统服务主控frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java→ AMS启动逻辑(systemReady)