Linux 内核如何启动 Android 的 init
2026/7/26大约 3 分钟系统启动Android 14Linux Kernelinit
Linux 内核如何启动 Android init
问题场景
Bootloader 已经跳转内核,但设备仍可能在创建 Android 属性和服务前失败。这个阶段的中心问题是:Linux 如何从“只有内核能运行”推进到执行用户空间 PID 1?
本文只追踪通用 Linux 启动职责与 Android ramdisk 中 /init 的交接。设备驱动顺序、内核 版本和压缩入口依产品而异,判断是否越过内核/用户空间边界要结合 PID 1、内核命令行和早期 日志。
核心结论
- Bootloader 跳转后,内核先建立内存、调度、中断、时钟和驱动等基础能力。
- 内核准备初始根文件系统后尝试执行 init;Android 启动镜像提供的
/init成为 PID 1。 /init已运行只能说明进入 Android 用户空间,不能说明分区、SELinux、Zygote 或 SystemServer 已就绪。- 内核日志的可见性受 build type、权限和 pstore/串口配置影响。
主流程
阶段一:接收 Bootloader 上下文
- 执行者:体系结构相关内核入口;输入:CPU 状态、设备树、cmdline。
- 动作:建立早期页表和可运行的 C 环境;下一跳:通用内核初始化。
- 边界:体系结构与设备相关。
阶段二:建立内核公共能力
- 执行者:内核启动线程;输入:编译配置与设备描述。
- 动作:初始化内存、调度、IRQ、时间、驱动模型和文件系统。
- 下一跳:
kernel_init;边界:仍在内核态。
阶段三:执行 Android init
- 执行者:内核 init 线程;输入:初始根文件系统与 init 路径。
- 动作:尝试执行用户空间 init;Android ramdisk 中
/init进入system/core/init/main.cpp。 - 下一跳:
FirstStageMain();边界:内核态到用户态,产生 PID 1。
关键源码
源码节点:Android init 的分派入口
- 方法:
main();路径:system/core/init/main.cpp;进程:PID 1。
int main(int argc, char** argv) {
// 省略ueventd、subcontext 等分派
if (is_first_stage) {
return android::init::FirstStageMain(argc, argv);
}
return android::init::SecondStageMain(argc, argv);
}结论:AOSP 源码可以直接证明 /init 进入 Android init 的阶段分派;在这之前的 kernel_init 细节应以设备实际内核树为准。
源码节点:first-stage init
- 方法:
FirstStageMain();路径:system/core/init/first_stage_init.cpp。 - 作用:建立最早期目录、设备节点与挂载条件,然后重新执行 init 进入后续阶段。
这个节点解释了为何“PID 1 已出现”仍可能看不到完整 /system 和 Framework:first stage 的目标只是为 second stage 创造条件。
验证与排障
环境:Android 设备已能连接 adb。读取 dmesg 在 user build 上通常受限;早期崩溃可能只能依靠串口或 pstore。
adb shell 'cat /proc/1/comm; readlink /proc/1/exe'
adb shell cat /proc/cmdline
adb shell 'cat /proc/uptime; getprop ro.boottime.init'
adb shell dmesg | head -n 80预期 PID 1 名称为 init。若完全没有 Android 属性但已有内核输出,检查 ramdisk、根文件系统和 init exec;若设备重启后 /sys/fs/pstore/ 有内容,优先查内核 panic 或 watchdog。/proc/cmdline 在新设备上可能只包含部分参数,另一些来自 bootconfig。
常见误区
- 内核不是通过 Binder 启动 init,而是执行用户空间程序。
- init 出现不代表分区挂载或 SELinux 策略已成功。
- AOSP Framework 源码树不一定就是设备正在运行的完整内核源码树。
源码入口
| 文件 | 关键位置 | 作用 |
|---|---|---|
| 见本章“关键源码”各节点 | 类名 / 方法名 | 证明主流程的关键动作 |
| Android 14 r75 对应源码文件 | 使用 rg -n 核对 | 发布前记录真实行号,避免跨 tag 漂移 |