典型的x86系统有固件(也称为BIOS或UEFI)存储在基于SPI的闪存芯片中。当电源启动时,处理器开始在复位向量处执行,该向量指向存储BIOS的内存映射SPI芯片。从这里开始,当BIOS完成平台的非initalization,加载引导加载程序,然后加载内核时,就会发生引导。
然而,处理器如何知道如何从SPI芯片中读取?我的意思是,到那时,处理器将不知道SPI协议,哪种芯片寄存器可以写命令,哪种寄存器可以找到读取的数据。阅读是如何在如此低的水平上发生的?
发布于 2020-02-13 10:36:11
Haswell+ CPU在供电时(在BIST内置的自测试之后)所做的第一件事是执行一个微编码例程( 英特尔TXT技术的一部分),在4GiB-40h获取适配并执行BIOS (认证代码模块),并最终在4GiB-10h继续执行测量引导,或者返回到遗留复位向量。
无论哪种方式,CPU都需要从内存窗口中获取指令--几个MiB刚好低于4GiB。
CPU没有SPI接口,出于安全考虑,对此窗口的请求总是重定向到DMI接口。
您可以在第八至第九代数据表第二卷的第2.6章中找到以下地图(即使在前几代,AFAIK也是如此):
与本段有关:
出于安全考虑,处理器将这个高BIOS范围正解码为DMI。这种正解码确保任何重叠范围都将被忽略。这确保引导向量和BIOS在PCH上执行。
使CPU从DMI接口启动,因此平台控制器集线器(Platform )处理请求。
请注意,即使在较旧的系统中,近4GiB窗口被减除到DMI接口(即只有在没有其他设备声明时才发送到DMI接口),引导几乎总是来自DMI接口本身。
新的正解码行为是防止启动攻击的一种安全措施。
如果您查看相对现代的PCH的数据表,即系列200,您会发现它支持LPC桥接或SPI接口后面的Flash。
我们将把自己局限于后者。
在该芯片组中,SPI桥是PCI设备31,功能15。
在其PCI配置空间中有标准寄存器和:
让我们集中讨论第二点:
需要注意的两件事:首先,这个寄存器要么启用,要么禁用,将内存访问从CPU发送到SPI,在4GiB以下的4MiB区域和其他地方。
第二个是默认值为0ffcfh,意味着默认情况下所有窗口都映射到SPI。
BIOS控制寄存器还选择SPI作为默认的引导接口,但这也是可配置的软带/引导引脚,IIRC。
最后但同样重要的是,当PCH看到像4 GiB-10h这样的地址时,它不能像它一样发送到Flash,因为它超出了Flash本身的范围。
它必须首先解码它,减去一个偏移量。但是,这个偏移取决于Flash的大小。
在PCH之前(我认为是围绕着descriptors.芯片组,在一些非最近的ICH8芯片组中),Flash是在没有ICH8的情况下使用的。
芯片组简单地将ROM从4GiB映射到使用别名的4GiB-16MiB,这意味着地址4GiB-X将映射到Flash大小- (X % Flash大小)。
其效果是,例如,一个2 MiB闪光灯出现8次映射在16 MiB窗口低于4 GiB限制。
在这些芯片组中,有引导引脚来配置Flash大小。
今天,用于PCH 使用描述符的Flash,其中flash被划分为区域( BIOS、ME、GbE等)。
只有BIOS区域被映射到CPU的地址空间中。有一个基于请求者id的安全描述符系统(由其PCI标识提供)。
有关本主题的介绍,请参阅这或更好的这以获得更完整的描述(有点过时,但仍然相关)。
区域在这里是相关的,因为它们在Flash描述符中列出了它们的偏移量和大小,因此PCH可以知道如何将CPU地址转换为Flash线性地址。
最后,SPI接口的MMIO寄存器允许原始访问Flash。可以合成命令来发送SPI总线,这样就可以重新编写Flash (例如)。
它们仍然受到应在数据表IIRC中列出的各种安全对策的制约。
https://stackoverflow.com/questions/60200796
复制相似问题