AI 技术博客
Android全栈9 分钟阅读4844

【全栈第21课】Bootloader→Kernel→init 开机全流程(阶段四实战开篇)

Android 全栈工程师进阶教程 第21课。Bootloader→Kernel→init 开机全流程(阶段四实战开篇)。基于公开 AOSP 知识整理,含原理、可编译示例、常见问题定位。

> 本文是《Android 全栈工程师进阶教程》系列第 21 课。完整 26 课见 GitHub 仓库

【全栈第21课】Bootloader→Kernel→init 开机全流程(阶段四实战开篇)


0. 这节课你将搞懂什么

从按电源键到看见桌面,中间每一棒发生了什么,以及"开不了机/卡 logo/卡开机动画"分别卡在哪一棒、怎么定位。 学完你能回答:Android 开机经过哪些阶段?我前面学的东西(HAL 的 class hal、SystemServer、bootphase)在开机流程里哪个位置?设备开不了机/卡 logo/卡动画,我该怎么判断卡在哪、去哪查日志?

1. 背景:开机是所有层的总集成

开机流程把你前面学的全部串起来:bootloader 加载 kernel → kernel 跑 init → init 拉起 HAL(L9 的 class hal)和 zygote → SystemServer 启动各服务(L3)→ 桌面起来。

理解开机流程 = 拿到一张"卡在哪一棒"的定位地图。这是处理"开不了机"类问题(高频且严重)的基础。

2. 全局图:完整开机链

① 按电源键 → PMIC 上电 → SoC 内 BootROM(固化在芯片,改不了)
② BootROM → 加载 Bootloader(高通 XBL/ABL,小米有 ABL 定制)
     ├ 校验镜像签名(AVB / verified boot)
     ├ 显示开机 logo
     └ 选 A/B slot
③ Bootloader → 加载 boot.img(GKI 内核 + ramdisk)→ 跳进 kernel
④ Kernel 启动
     ├ 解压、初始化内存/调度/built-in 驱动
     └ 挂载 ramdisk → 运行 /init(第一个用户态进程,pid 1)
⑤ init(system/core/init)
     ├ 解析 init.rc
     ├ 挂载 system/vendor/data 分区
     ├ 按 class 启动 service(class core → main → hal → late_start)  ← L9 HAL 在 class hal
     └ 触发 property trigger
⑥ init 启动 zygote(app_process)
⑦ Zygote → fork SystemServer                                       ← L2/L3 的舞台
⑧ SystemServer 三批 + bootphase 启动各服务                          ← L3
⑨ AMS 启动 Launcher → BOOT_COMPLETED(L3 phase 1000)
⑩ 看见桌面

3. 前面课在开机流程的位置

你学过的在开机哪一步
HAL 的 class hal(L9)第 ⑤ 步 init 在 hal 阶段拉起
内核驱动 .ko / modules.load(L13)第 ④⑤ 步加载
SystemServer 三批启动(L3)第 ⑧ 步
onBootPhase BOOT_COMPLETED(L3)第 ⑨ 步
Binder/servicemanager(L1)servicemanager 在 init 早期(class core)起,⑦⑧ 才能 addService

4. 前置准备

  • 依赖前面所有课(开机是总集成)。
  • 本课偏知识地图 + 定位方法,产出文档。

5. 动手:理解"卡在哪一棒"的定位地图(核心)

开机不出问题就一路到桌面;出问题就卡在某一棒。关键是先判断卡在哪一棒,再针对性查。

现象卡在哪一棒去哪查
黑屏完全没反应①BootROM/PMIC/电源硬件、电池、上电时序(示波器/万用表)
卡开机 logo 不动②③④ Bootloader/kernel 早期fastboot 日志、串口、kernel 早期 panic、/proc/last_kmsg
反复重启卡 logokernel panic / verified boot 失败ramdump(L24)、AVB 日志
卡 bootanimation(开机动画)不进桌面⑤⑥⑦⑧ init/zygote/SystemServerlogcat、init 日志、SystemServer 卡哪个服务
进桌面后又重启⑧⑨ SystemServer 崩 / watchdoglogcat、tombstone、dropbox

分水岭:logo 之前卡 = bootloader/kernel(底层);logo 之后/动画卡 = init/framework(上层)。 先用这条线把范围砍一半。

6. 看底层:为什么 servicemanager 必须最早起

init.rc 里 service 按 class 分阶段启动:

class core       最早:ueventd(建设备节点)、logd(日志)、servicemanager(L1 黄页)
class main       主要服务
class hal         HAL 进程(L9 的 hello-hal 在这)
class late_start  晚启动

servicemanager 在 class core 早早起来,因为后面 SystemServer(第⑧步)要 addService、HAL 要注册,都依赖它。如果 servicemanager 起不来,整个 Binder 体系瘫痪,开不了机。这解释了为什么它的启动顺序这么靠前。

7. 编译 & 运行(观察 + 抓日志)

adb shell getprop | grep -iE "boot|sys.boot"      # 开机状态属性(sys.boot_completed=1 表示开机完成)
adb shell dmesg | grep -iE "init|boot"             # kernel/init 日志
adb logcat -b all | grep -iE "SystemServer|Boot"   # framework 启动日志
adb shell cat /proc/last_kmsg 2>/dev/null          # 上次开机的 kernel 日志(查反复重启)
adb shell cat /sys/fs/pstore/console-ramoops-0     # 死机现场(L24)
fastboot getvar current-slot                        # 当前 A/B slot(在 fastboot 模式)

> 验证状态(诚实):本课为开机流程知识 + 定位方法,无编译产物。命令为标准开机调试命令。

8. 踩坑提醒

  1. 黑屏 vs 卡 logo 别混:黑屏(完全没反应)多是硬件/电源;卡 logo 是 bootloader/kernel 起来了但走不下去。判断错方向就错。
  2. logcat 在卡 logo 阶段没用:logcat 是 framework 起来后才有的,卡 logo(framework 还没起)要看 dmesg/串口/last_kmsg。
  3. 反复重启看上次日志:正在重启抓不到现场,看 /proc/last_kmsg/pstore 是上一次的崩溃记录。
  4. A/B slot 启动失败回退:一个 slot 启动失败会自动回退另一个,看 current-slot 是不是变了。

9. 常见问题分析与定位(开机实战)

9.1 常见问题清单

  1. 卡开机 logo(进不去)
  2. 卡 bootanimation(开机动画转圈不进桌面)
  3. 反复重启(boot loop)
  4. 进桌面后几秒又重启
  5. 开机特别慢

9.2 分析与定位

① 卡 logo — bootloader/kernel 早期。

# 接串口看 bootloader/kernel 早期日志(最直接)
adb reboot bootloader; fastboot getvar all     # bootloader 信息(能进 fastboot 说明 bootloader 活)
adb shell cat /proc/last_kmsg                   # 若能短暂连上,看 kernel 卡哪
  • 能进 fastboot 但不进系统 → kernel/ramdisk 问题或 AVB 校验失败;连 fastboot 都进不去 → bootloader/硬件。

② 卡 bootanimation — init/zygote/SystemServer。

adb logcat -b all | grep -iE "SystemServer|zygote|Boot"
adb shell ps -A | grep -iE "system_server|zygote"   # 这俩进程起了吗
adb pull /data/anr/                                  # SystemServer 卡住会被 watchdog 抓 trace
  • system_server 没起 → zygote/init 问题;system_server 起了但卡 → 看它卡在哪个服务(traces.txt,接 L3)。

③ boot loop — kernel panic / SystemServer 反复崩。

adb shell cat /sys/fs/pstore/console-ramoops-0   # kernel panic 现场(L24)
adb logcat -b all | grep -iE "FATAL|watchdog|SystemServer.*crash"
  • kernel panic → L24 看栈;SystemServer 崩 → logcat 看哪个服务抛异常。

④ 进桌面后重启 — SystemServer 崩或 watchdog 超时。

adb logcat | grep -iE "watchdog|FATAL EXCEPTION.*system_server"
adb pull /data/tombstones/   # native crash
adb pull /data/system/dropbox/   # crash 记录

⑤ 开机慢 — 某服务/HAL 启动耗时。

adb logcat | grep -i "SystemServerTiming"   # 各服务启动耗时(L3)
adb shell dmesg | grep -i "initcall"          # 内核 init 耗时

9.3 定位决策树

开机出问题
├─ 先判断分水岭:logo 前(bootloader/kernel)还是 logo 后(init/framework)
├─ 黑屏没反应 → ①硬件/电源(示波器/万用表)
├─ 卡 logo → fastboot getvar(bootloader 活吗)+ last_kmsg → kernel/AVB/bootloader
├─ 卡 bootanimation → logcat SystemServer + ps 看 system_server/zygote 起没 + /data/anr
├─ boot loop → pstore/last_kmsg(kernel panic,L24)+ logcat(SystemServer 崩)
├─ 进桌面后重启 → logcat watchdog/FATAL + tombstone + dropbox
└─ 开机慢 → SystemServerTiming(L3)+ dmesg initcall

10. 小结

  1. 开机链十步:BootROM→Bootloader→kernel→init→zygote→SystemServer→Launcher。
  2. 前面课的位置:HAL class hal 在 init(⑤),SystemServer 在 ⑧,BOOT_COMPLETED 在 ⑨。
  3. 分水岭定位:logo 前卡 = bootloader/kernel;logo 后/动画卡 = init/framework。先砍一半范围。
  4. 卡 logo 看 dmesg/last_kmsg/串口(logcat 还没有);卡动画看 logcat/SystemServer
  5. 排查口诀:先判分水岭;卡 logo 查 fastboot+last_kmsg;卡动画查 SystemServer+ps;boot loop 查 pstore。

下节预告

L22:跨层问题定位武器库 —— 系统梳理每一层用什么工具查问题(logcat/dmesg/ftrace/perfetto/ramdump),建立完整的定位工具地图。

评论