1. 课程导入

在嵌入式Android设备开发中,从一块空白eMMC到屏幕上出现开机动画,中间要跨越镜像编译、分区烧录、BootROM引导、内核启动、init挂载、Zygote孵化等一连串环节。任何一个环节的参数错误、镜像不匹配或硬件时序异常,都会让设备停在黑屏、反复重启或卡在Logo。本课程的目标,是让学习者建立一条从"烧录"到"启动"再到"调试"的完整能力链,既能按流程把系统跑起来,也能在它跑不起来时快速定位问题。

一、学习目标:从会操作到会诊断

本课程不满足于"照着工具点一遍"。学完之后,你应当能够独立完成以下四类任务:

  • 烧录层面:理解分区表、镜像类型与烧录协议,能使用厂商工具或开源工具完成整包与单分区烧录。
  • 启动层面:说清从复位向量到Android Framework的每一级引导,知道每一级由谁加载、校验什么、失败会怎样。
  • 调试层面:能通过串口日志、内核打印、logcat、dmesg、fastboot状态判断故障发生在哪一级。
  • 复盘层面:能把一次故障整理成"现象—证据—根因—修复—验证"的闭环记录,形成可复用的排障经验。
学习主线可以概括为一句话:先让系统能启动,再让启动可观测,最后让故障可定位。烧录是入口,启动是主干,调试是贯穿始终的手段。

二、核心概念:五个必须建立的心智模型

在动手之前,先建立五个关键概念,它们会在后续每一章反复出现。

  1. 分区与镜像:Android设备通常包含boot、init_boot、vendor_boot、system、vendor、userdata、misc等分区。每个分区对应一个镜像文件,烧录本质是把镜像写入对应分区的正确偏移。
  2. 引导链(Boot Chain):典型顺序为 BootROM → SPL/Preloader → U-Boot/LK → Kernel → init → Zygote → SystemServer。每一级只信任上一级的校验结果。
  3. 启动模式:正常启动、fastboot、recovery、EDL/下载模式。不同模式决定主机能用什么协议与设备通信。
  4. 日志通道:串口(UART)输出最早期的BootROM与SPL信息,内核用dmesg,用户空间用logcat。越早的问题越依赖串口。
  5. 校验与签名:AVB、dm-verity、vbmeta决定镜像是否被允许启动。校验失败常表现为"启动即黑屏"或"进入fastboot"。

三、整体知识框架:一张图看清全链路

下图把本课程的知识结构按"主机侧—传输侧—设备侧—观测侧"四个区域展开,并标出各阶段的主要故障点。它既是知识地图,也是后续排障时的定位参照。

Android 烧录启动与故障调试 · 全链路知识框架 主机侧(Host) 源码编译 / 镜像产出 boot.img system.img … 烧录工具 fastboot / QFIL / 厂商工具 分区表与配置 partition.xml / GPT 签名与校验 AVB / vbmeta 调试主机环境 adb / 串口终端 / 抓log 常见故障点 镜像不匹配 · 分区错位 签名失败 · 工具版本不符 传输侧 USB fastboot协议 UART 串口日志 ADB shell / logcat 网络 adb over TCP 故障点 驱动异常 线缆/供电不足 设备侧(Device Boot Chain) ① BootROM(固化,不可改) 复位向量 · 加载SPL/Preloader ② SPL / Preloader 初始化DDR · 加载U-Boot/LK ③ U-Boot / LK 读取分区 · 校验boot · 传参 ④ Kernel + dtb 驱动初始化 · 挂载根文件系统 ⑤ init(第一阶段/第二阶段) 解析init.rc · 启动服务 ⑥ Zygote → SystemServer 孵化应用进程 · 启动Framework 常见故障点 DDR训练失败 · 镜像损坏 · AVB校验不过 · init.rc错误 观测侧(Debug) 串口日志 最早、最底层证据 dmesg / kmsg 内核驱动与挂载 logcat Framework与应用层 fastboot getvar 分区与状态查询 崩溃与重启记录 last_kmsg / pstore 排障原则 先看最早日志 再逐级向上定位 日志反向定位故障级

四、实战路线图:六步走完一次完整调试

把上面的框架落到操作上,可以归纳为一条可重复执行的路线。建议在真实项目中有意识地按这六步推进,而不是遇到问题就随机试错。

步骤 关键动作 主要工具/命令 成功判据
1. 环境确认 确认设备型号、芯片平台、工具版本、驱动状态 lsusb、fastboot devices、串口终端 主机能识别设备并进入目标模式
2. 镜像准备 核对分区表与镜像清单,确认签名配置 partition.xml、vbmeta、编译产物目录 镜像与分区一一对应且校验通过
3. 执行烧录 整包或单分区烧录,观察进度与返回码 fastboot flash、QFIL、厂商工具 烧录无报错,分区写入成功
4. 启动观测 接串口,从复位开始记录完整启动日志 串口工具、dmesg、logcat 日志能连续推进到目标阶段
5. 故障定位 找到日志中断或报错的第一现场 grep、last_kmsg、pstore 能指出失败发生在哪一级
6. 修复验证 针对性修改后重新烧录并回归验证 重烧、重启、压力测试 问题复现消失且无新问题

五、典型场景与常见误区

举一个真实感较强的场景:设备烧录完成后上电,串口只打印到Preloader就停止,屏幕无任何反应。此时如果直接怀疑内核,方向就错了——日志停在Preloader,说明问题在DDR初始化或SPL加载阶段,应优先检查DDR参数配置、供电和Preloader镜像是否与芯片型号匹配。这就是"按日志最早中断点定位"的价值。

初学者最常见的三个误区:
一是跳过串口直接看logcat,而logcat只能看到用户空间,早期引导问题完全看不到;
二是镜像与分区张冠李戴,把vendor_boot烧进boot分区,导致启动直接失败;
三是忽略签名与校验,改了镜像却没重新签名,设备因AVB校验失败而拒绝启动。

下面是一段典型的启动日志片段,后续章节会反复用到这种"逐级推进"的阅读方式:

[BootROM] reset vector, loading preloader...
[Preloader] DDR init OK, loading lk...
[LK] boot mode: normal, loading boot.img
[Kernel] Linux version 5.10 ...
[Kernel] init: init first stage started
[init] parsing init.rc ...
[init] starting zygote ...
[Zygote] SystemServer starting ...

当这条链在某一级断掉,断点本身就是最有价值的线索。本课程后续将沿着这条链逐级展开:先讲烧录工具与分区,再讲引导链与内核,然后讲init与Framework启动,最后集中训练日志分析与故障复盘方法。掌握这条主线,你面对的不再是"设备起不来"这种模糊描述,而是"Preloader之后DDR训练失败"这样可操作的判断。