第二章 海思芯片启动流程:从复位到系统运行
大家好,我是你们的嵌入式系统讲师。今天我们来聊聊海思芯片的启动流程。说实话,这个主题我讲了不下几十次,但每次都有新感悟。芯片启动,说白了就是一颗芯片从"死"到"活"的过程。你想想看,一个刚上电的芯片,内存里全是随机数据,它怎么知道该执行什么?
我在项目中遇到过不少启动相关的问题,有些问题查了好几天,最后发现是某个时序没配好。嗯,今天就把这些经验分享给大家。
2.1 芯片上电复位:一切从这里开始
芯片上电后,第一件事就是复位。复位信号会强制芯片进入一个已知的初始状态。海思芯片的复位分为几种:
- 上电复位(POR):芯片刚通电时触发
- 硬件复位:通过复位引脚触发
- 看门狗复位:系统卡死时自动触发
- 软件复位:通过寄存器触发
我个人习惯在硬件设计时,把复位电路单独拿出来仔细检查。曾经有个项目,因为复位电容选大了,导致芯片上电后迟迟不能进入正常工作状态,查了两天才发现是复位时间太长。
2.2 BootROM执行:芯片的"出厂设置"
复位完成后,CPU会从固定的地址开始执行代码。这个地址指向的就是芯片内部的BootROM。BootROM是芯片出厂时固化的一段程序,你改不了它。
BootROM主要做三件事:
- 初始化最基本的硬件:比如时钟、内存控制器、串口等
- 检测启动介质:看看是从NAND Flash、eMMC、SPI Flash还是UART启动
- 加载下一级Bootloader:把Fastboot或Uboot从存储介质中读到内存里
我记得有一次调试,芯片死活起不来,串口没有任何输出。后来用示波器一量,发现BootROM根本没执行完——因为时钟晶振没起振。这种问题其实挺常见的,大家遇到启动失败,先检查时钟和电源。
关键点:BootROM的执行时间通常在几十到几百毫秒之间。如果超过1秒还没有任何输出,基本可以断定硬件有问题。
2.3 Fastboot/Uboot加载:真正的"引导"
BootROM把Bootloader加载到内存后,控制权就交给了Fastboot或Uboot。海思芯片通常使用Fastboot,但有些平台也支持Uboot。
Bootloader要做的事情比BootROM多得多:
- 初始化DDR内存
- 初始化存储控制器(eMMC、NAND等)
- 初始化网络接口(如果需要网络启动)
- 加载内核和设备树到内存
- 传递启动参数给内核
这里我特别想强调一下设备树(Device Tree)。很多刚入行的朋友不理解设备树是干嘛的。说白了,设备树就是告诉内核:"你的硬件长什么样,有哪些外设,地址是多少,中断号是多少。"没有设备树,内核根本不知道该怎么跟硬件打交道。
小技巧:调试Bootloader时,可以在串口打印中加入时间戳。这样你能清楚地看到每个阶段花了多少时间,对优化启动速度非常有帮助。
2.4 内核启动:操作系统登场
Bootloader把内核加载到内存后,会跳转到内核入口地址。内核开始执行后,会做一系列初始化工作:
| 阶段 | 主要工作 | 耗时(典型值) |
|---|---|---|
| 解压内核 | 如果内核是压缩的,先解压 | 100-500ms |
| 架构初始化 | 设置MMU、中断向量表等 | 50-100ms |
| 设备驱动初始化 | 根据设备树初始化各外设 | 200-1000ms |
| 挂载根文件系统 | 找到并挂载根文件系统 | 100-500ms |
我曾经遇到一个性能问题:内核启动花了整整5秒。后来发现是某个驱动在初始化时做了大量的延时等待。优化后,启动时间降到了1.2秒。所以大家写驱动时,尽量不要用mdelay这种粗暴的延时方式。
2.5 根文件系统挂载:最后的拼图
内核启动的最后一步,就是挂载根文件系统。根文件系统里放着什么呢?
- init进程(通常是systemd或busybox init)
- 各种系统库(libc、libm等)
- 配置文件(/etc目录下的各种配置)
- 应用程序
根文件系统的类型有很多种:
- initramfs:集成在内核镜像中,启动快但占用内存
- ext4:最常用的文件系统,支持读写
- squashfs:只读压缩文件系统,节省空间
- NFS:网络文件系统,开发调试时很方便
我个人在开发阶段喜欢用NFS挂载根文件系统。为什么呢?因为修改了文件系统内容后,不需要重新烧录,直接重启就行。但产品量产时,一定要换成ext4或squashfs,毕竟网络不是随时都有的。
注意:根文件系统挂载失败是启动失败的常见原因。如果内核启动日志最后停在"VFS: Cannot open root device",那基本就是根文件系统的问题。检查一下内核启动参数中的root=是否正确,或者文件系统镜像是否损坏。
2.6 启动流程总结
好了,我们来梳理一下整个启动流程:
- 上电复位 → CPU从固定地址开始执行
- BootROM执行 → 初始化基本硬件,加载Bootloader
- Fastboot/Uboot执行 → 初始化DDR、存储等,加载内核
- 内核启动 → 解压、初始化、驱动加载
- 挂载根文件系统 → 启动init进程,系统正式运行
整个流程下来,快的设备能在2-3秒内完成,慢的可能要5-10秒。如果你做的是消费类产品,启动速度直接影响用户体验。我见过有些产品为了追求1秒开机,把内核裁剪得只剩几百KB,连不必要的驱动都去掉了。
嗯,这就是海思芯片的启动流程。下一章我们会深入讲解BootROM的细节,包括启动介质选择、安全启动等高级话题。有什么问题,欢迎在课后交流。