第二章 启动流程全景图:从按下电源键到操作系统加载

各位同学,今天我们来聊聊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启动分几个子阶段:

  1. SEC(Security):验证BIOS本身的完整性。嗯,这里要注意,AMD的PSP会参与这个验证。
  2. PEI(Pre-EFI Initialization):初始化CPU、芯片组、内存。DDR训练就在这个阶段完成。
  3. DXE(Driver Execution Environment):枚举所有外设,加载驱动。PCIe设备、SATA控制器、USB控制器都在这里初始化。
  4. 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:最后的冲刺

内核拿到控制权后,会做三件事:

  1. 解压自身:内核镜像通常是压缩的,需要先解压到内存中。
  2. 初始化核心子系统:调度器、内存管理、中断系统、时间子系统。
  3. 加载驱动:根据设备树或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到底是怎么做安全启动的。到时候我会拿一个实际案例来拆解,保证让你有收获。