4、安全启动流程(上):从Reset到PSP初始化、验证BIOS第一阶段(Bootloader)

好,咱们今天聊聊AMD平台安全启动的起点。说白了,就是从你按下电源键那一刻,到PSP(Platform Security Processor,平台安全处理器)把BIOS的第一段代码——Bootloader——验明正身的过程。

我个人习惯把安全启动看作一场接力赛。第一棒,就是CPU Reset。第二棒,是PSP。它得先把自己收拾利索了,才能去验证别人。嗯,这里面的门道不少,咱们一步步拆开看。

4.1 Reset之后,谁先跑?

你想想看,x86 CPU一上电,复位向量指向的是FFFF_FFF0h,传统上这是BIOS的入口。但在现代AMD平台上,事情没那么简单。

实际上,真正的“第一个执行者”是PSP内部的ARM Cortex-A5核心。x86核心此时还处于复位状态,被PSP牢牢按住。为什么会这样?因为安全启动要求“可信根”必须是一个独立、不可篡改的硬件模块。PSP就是AMD的可信根。

关键点:PSP拥有自己的ROM(Boot ROM),这是芯片出厂时固化的,物理上不可修改。它是整个信任链的起点,也就是所谓的“硬件可信根”。

我在项目中遇到过一位同事,他总以为BIOS是第一个跑的,结果调试安全启动时怎么都过不去。后来我告诉他,你得先看PSP的脸色。他恍然大悟,从此再没犯过这个错。

4.2 PSP初始化:先把自己收拾利索

PSP的Boot ROM上电后,第一件事是自我初始化。这个过程大致分三步:

  1. 硬件自检:检查PSP内部的SRAM、加密引擎、DMA控制器等是否正常。说白了,就是看看自己胳膊腿儿有没有毛病。
  2. 密钥加载:从一次性可编程存储器(OTP,One-Time Programmable)中读取芯片唯一的密钥。这个密钥是出厂时烧录的,用于后续的签名验证。
  3. 建立安全环境:初始化安全内存区域,确保后续的代码和数据不会被x86侧或其他外设窥探。

避坑指南:我曾经调试过一块板子,PSP死活初始化不过。查了半天,发现是OTP fuse烧录时出了问题,导致密钥读取失败。所以,如果你遇到PSP启动卡死,先检查fuse配置,别急着怀疑代码。

嗯,这里要注意,PSP的初始化过程是高度并行的。它会在初始化硬件的同时,开始从SPI Flash中读取BIOS的第一段数据。这个设计很巧妙,能节省宝贵的启动时间。

4.3 验证BIOS第一阶段:Bootloader

PSP初始化完成后,它手里已经有了芯片密钥和一段从Flash读来的数据。这段数据就是BIOS的Bootloader,也叫“PSP目录”或“BIOS第一阶段镜像”。

验证过程,我习惯用一张表来概括:

步骤 动作 说明
1 读取Bootloader头部 获取镜像大小、版本、签名位置等信息
2 计算镜像哈希 使用SHA-256或SHA-384对整个Bootloader镜像计算摘要
3 验证数字签名 用OTP中的公钥解密签名,与计算出的哈希比对
4 检查版本号 防止回滚攻击,确保Bootloader版本不低于某个阈值
5 加载并跳转 验证通过后,将Bootloader加载到PSP的SRAM中,并跳转执行

你可能会问,为什么要验证版本号?我举个例子。假设黑客拿到了一个旧版本的Bootloader,里面有个已知漏洞。如果没有版本检查,他就能用这个旧镜像绕过安全启动。这就是所谓的“回滚攻击”。AMD在PSP里硬编码了最低版本号,低于这个版本的镜像直接拒绝执行。

警告:千万不要在生产环境中关闭版本检查!我见过一些开发板为了调试方便,把版本检查跳过了。结果产品上市后,被黑客利用旧版本漏洞攻破了。这个教训很深刻。

4.4 签名验证的细节

签名验证是安全启动的核心。AMD使用的是RSA-2048或RSA-4096算法。公钥存储在OTP中,私钥则由主板厂商(如华硕、微星)或OEM厂商保管。

具体流程是这样的:

  • PSP从OTP中读取公钥哈希(不是公钥本身,而是它的哈希值)。
  • Bootloader镜像里附带了一个证书链,包含公钥和签名。
  • PSP先验证证书链的有效性,确保公钥是可信的。
  • 然后用公钥解密签名,得到原始哈希值。
  • 最后对比自己计算的哈希和原始哈希,一致则通过。

这里有个细节:OTP里存的是公钥的哈希,而不是公钥本身。为什么?因为OTP空间有限,存一个哈希值(32字节)比存一个公钥(几百字节)省地方。而且,哈希值也能防止公钥被篡改。

我记得有一次,客户反映他们的主板无法启动。我远程一看,发现是BIOS镜像的签名证书链过期了。嗯,你没听错,证书也有有效期。虽然Bootloader本身没有过期时间,但签名证书链如果过期,PSP会认为它不可信。所以,更新BIOS时别忘了同步更新证书。

4.5 Bootloader执行与下一阶段

Bootloader被PSP验证通过并加载到SRAM后,PSP会跳转到它的入口地址。Bootloader的任务是什么?

  • 初始化SPI Flash控制器,以便后续读取更大的BIOS镜像。
  • 验证BIOS的第二阶段(通常是BIOS的完整镜像或压缩包)。
  • 释放x86核心,让它开始执行BIOS的初始化代码。

说白了,Bootloader就是PSP的“小跟班”,负责把接力棒传给下一棒。它本身很小,通常只有几十KB,但功能很关键。

个人经验:调试Bootloader时,我建议用逻辑分析仪抓SPI Flash的通信。你能清楚地看到PSP读了哪些地址、验证了哪些数据。有一次,我发现Bootloader加载到一半卡住了,原来是Flash的时序参数配置不对。调整后,问题迎刃而解。

好了,这一章的内容就到这里。从Reset到PSP初始化,再到验证Bootloader,每一步都环环相扣。下一章,我们会继续深入,看看Bootloader如何验证BIOS的完整镜像,以及x86核心是如何被“唤醒”的。

你想想看,安全启动就像盖房子,地基打不好,后面全白搭。PSP和Bootloader就是那个地基。理解了它们,你才算真正入了AMD安全启动的门。