第二章 启动流程全景图:从按下电源键到操作系统加载
各位同学,今天我们来聊聊AMD嵌入式系统的完整启动链路。说实话,我见过不少工程师,做了好几年固件开发,却对整个启动流程一知半解。他们能调通某个模块,但问起「按下电源键后到底发生了什么」,往往说不清楚。
嗯,这其实很危险。你想想看,启动流程是整个系统的根基。根基不稳,后面调驱动、调OS都是白搭。我个人习惯,接手一个新平台时,第一件事就是通读启动流程文档。今天我就把这条链路掰开揉碎了讲给你听。
2.1 启动链路总览
AMD嵌入式系统的启动,说白了就是一条流水线。从按下电源键到OS加载,中间经过四个核心阶段:
| 阶段 | 存储介质 | 主要任务 | 典型耗时 |
|---|---|---|---|
| ROM Stage | 芯片内部ROM | 硬件初始化、安全验证 | 几十毫秒 |
| BIOS/UEFI | SPI Flash | 平台初始化、外设枚举 | 几百毫秒到几秒 |
| Bootloader | 存储设备(eMMC/NAND) | 加载OS内核、传递参数 | 几十到几百毫秒 |
| OS Kernel | 内存 | 系统调度、驱动加载 | 几秒 |
每个阶段都有它的使命。少一个环节,系统就起不来。我在项目中遇到过客户自己改启动流程,跳过了某个安全校验,结果产品在高温下频繁死机——这就是典型的「省事惹麻烦」。
2.2 ROM Stage:芯片的第一口呼吸
按下电源键的那一刻,CPU复位,PC指针直接指向芯片内部ROM的固定地址。这个ROM是出厂固化的,你改不了,我也改不了。
ROM Stage干三件事:
- 硬件自检:检查CPU核心、缓存、关键寄存器是否正常。说白了就是「我还能不能干活」。
- 安全启动校验:验证下一阶段代码(通常是BIOS)的数字签名。AMD平台有PSP(Platform Security Processor)来做这件事。
- 加载BIOS到SRAM:从SPI Flash中读取BIOS代码,解压后放到芯片内部的SRAM中。
关键点:ROM Stage运行在芯片内部SRAM中,此时外部内存(DDR)还没初始化。所以代码体积必须小,通常只有几十KB。
为什么会这样?因为DDR初始化需要复杂的时序训练,而ROM Stage还没走到那一步。我刚开始做AMD平台时,总想往ROM Stage里塞功能,后来发现根本塞不下——空间就那么点,还得留够安全校验的余量。
2.3 BIOS/UEFI Stage:真正的重头戏
BIOS阶段,我个人认为是整个启动流程中最复杂的部分。AMD平台用的是UEFI架构,不再是传统BIOS那套实模式了。
UEFI启动分几个子阶段:
- SEC(Security):验证BIOS本身的完整性。嗯,这里要注意,AMD的PSP会参与这个验证。
- PEI(Pre-EFI Initialization):初始化CPU、芯片组、内存。DDR训练就在这个阶段完成。
- DXE(Driver Execution Environment):枚举所有外设,加载驱动。PCIe设备、SATA控制器、USB控制器都在这里初始化。
- BDS(Boot Device Selection):选择启动设备。是从eMMC启动?还是从U盘?还是网络启动?
避坑指南:我曾经在PEI阶段遇到过DDR训练失败的问题。现象是板子偶尔能启动,偶尔卡死。查了两天才发现是PCB走线等长没做好。所以做硬件设计时,DDR走线一定要严格遵循AMD的layout guide,别自己发挥。
BIOS阶段还有一个重要任务:构建ACPI表和UEFI运行时服务。这些数据结构会被传递给OS,告诉OS「你的硬件长什么样」。比如CPU有几个核心、内存有多大、中断控制器怎么配置。
2.4 Bootloader Stage:承上启下
BIOS执行完BDS后,会从启动设备中加载Bootloader。在AMD嵌入式平台上,常见的Bootloader有U-Boot、GRUB,或者一些轻量级的方案。
Bootloader的核心任务:
- 加载OS内核:从文件系统(FAT、ext4等)中读取内核镜像。
- 设置启动参数:告诉内核内存布局、设备树信息、命令行参数。
- 跳转到内核:关闭MMU和缓存,跳转到内核入口点。
注意:Bootloader和BIOS之间有一个接口规范,叫UEFI Boot Protocol。如果你的Bootloader不遵守这个规范,BIOS可能根本不认它。我见过有人自己写Bootloader,结果忘了实现ExitBootServices接口,内核一启动就崩溃。
你想想看,Bootloader其实是个「翻译官」。它把BIOS准备好的硬件信息,翻译成OS能理解的格式。翻译错了,OS就迷路。
2.5 OS Kernel Stage:最后的冲刺
内核拿到控制权后,会做三件事:
- 解压自身:内核镜像通常是压缩的,需要先解压到内存中。
- 初始化核心子系统:调度器、内存管理、中断系统、时间子系统。
- 加载驱动:根据设备树或ACPI表,加载对应的设备驱动。
到了这一步,启动流程基本结束。用户会看到登录界面,或者控制台提示符。
但这里有个容易被忽略的点:启动时间优化。很多嵌入式产品对启动时间有硬性要求,比如车载系统要求3秒内显示倒车影像。这时候你就得回头去优化每个阶段:
- ROM Stage:能不能减少安全校验的等待时间?
- BIOS Stage:能不能跳过某些外设的初始化?
- Bootloader:能不能用更快的存储接口?
- OS Kernel:能不能裁剪掉不需要的驱动?
实战经验:我做过一个项目,客户要求启动时间从8秒降到3秒。最后发现瓶颈在BIOS的DDR训练上,那个训练算法太保守了。我们和AMD的FAE一起调了训练参数,硬生生省了2秒。所以说,启动优化是个系统工程,每个环节都得抠。
2.6 总结
好了,整个启动链路就是这样:
电源键 → ROM Stage(硬件自检+安全校验)→ BIOS/UEFI(平台初始化+外设枚举)→ Bootloader(加载内核)→ OS Kernel(系统启动)
每个阶段都有它的职责,也有它的坑。我建议你拿到一块新板子时,先别急着写驱动,而是用串口把启动日志抓下来,逐行分析。你会发现,很多问题在启动阶段就已经埋下了伏笔。
下一章,我们会深入ROM Stage,看看AMD的PSP到底是怎么做安全启动的。到时候我会拿一个实际案例来拆解,保证让你有收获。