今天的BIOS如何超过64KB?

时间:2019-05-20 07:26:39

标签: x86 bios

AFAIK,BIOS大小限制为段大小(0xFFFF)。但是,如今许多BIOS都超过了64KB,通常超过10MB。它怎么做到的?

2 个答案:

答案 0 :(得分:5)

64KiB限制一直是硬件限制,而不是软件限制。 要点是重新控制从内存到固件Flash ROM的内存访问。
这是允许更大的Flash ROM所要做的,但是历史很复杂。


CPU通过至少一个外部芯片访问固件(用于获取指令或数据)。
现代的层次结构就是这样:

Core --[QPI/UPI]--> System Agent --[DMI]--> PCH --[SPI/LPC]--> FLASH ROM

一个比较老的是:

CPU --[FSB]--> North Bridge/MCH --[DMI/Proprietary]--> South Bridge/ICH --[LPC] --> FLASH ROM

一个更老的是:

CPU --[BUS]--> System Controller --> FLASH ROM

注意:闪存ROM通常通过SuperIO芯片或嵌入式控制器连接到LPC。

为使CPU能够访问固件,部分内存地址被盗并重定向到Flash ROM。
这是通过配置CPU和Flash ROM之间的所有中间节点来完成的。

此窗口的大小设置为64KiB或128KiB(对应于范围0xf0000-0xfffff0xe0000-0xfffff),但这是一个设计决策(允许具有640KiB的RAM和320 / 256KiB扩展ROM)。
可以将窗口设计为512KiB或更高(尽管RAM会受到限制)。

无论如何,将该窗口设置为64KiB并进行更改会破坏该软件,因此它没有(并且没有)扩展。
当386出现时,CPU可以寻址超过1MiB(+ 64KiB-16B),实际上这是在286中使用24位地址空间“原型化”的,机会来了。

加电时,CPU开始像16位CPU一样在CS:IP = 0xf000:0x0fff处获取指令,但是(由于段寄存器在内部的工作方式)该逻辑地址未转换为0xffff0(因为它是16位CPU的情况),但0xfffffff0(比4GiB限制低16个字节)。
这样做是为了向后兼容(对软件可见的CS:IP对是不变的),同时允许映射更大的Flash ROM。
当然,也需要将4GiB附近的地址重定向(窃取)到Flash ROM。

4GiB地址空间不会受到固件窗口大小的影响,而不会像1MiB地址空间那样受到影响,因此4GiB处的窗口更大。
可以根据需要将窗口的大小设置为大(与其他系统设备兼容),但是有一个陷阱(实际上是两个)。

  1. 在4GiB-18MiB上,有一个始终无法访问的区域,被LAPIC(CPU内部块)遮盖了,该区域是可移动的,可以禁用,但默认情况下为4GiB-18MiB。
    因此,例如30MiB的Flash ROM将部分无法访问。
  2. PCH SPI模块最多支持8MiB的窗口。

固件如何为20MiB? 如今,固件主要由四个组件组成:

  • UEFI / BIOS
  • 英特尔ME
  • 1Gbs以太网
  • RAID控制器

以上讨论的窗口仅适用于UEFI / BIOS。
ME固件具有其自己的窗口,以太网和RAID控制器是PCIe设备,可以利用任何PCI窗口。


综合而言,固件分为多个组件,其中大多数遵循PCI(e)设计。其余的具有足够大的特殊内存窗口。

那为什么仍然要说BIOS限于段大小呢?
因为当CPU从0xfffffff0引导时,它实际上处于16位/ 32位混合模式,因此它在“内存结束”之前(在4GiB限制之前)只有16个字节,但是任何远距离跳转都会重新加载CS按照16位规则,将CPU限制在1MiB下限。
因此旧的64KiB / 128KiB窗口仍然存在,并且已映射到闪存的相同区域。
这使固件大于16B并根据需要配置系统(例如,仅将16位服务映射到下部窗口)。

答案 1 :(得分:0)

现代固件无法在16位实模式下运行;引导后立即切换到保护模式或长模式。 (它可以包含非代码图像)。

(这是一个有点麻烦的答案,因为我不知道具体细节。我认为有关堆栈映射BIOS和/或CS的问题已经在Stack Overflow上出现了。 :IP在启动时CPU跳至。

如果您告诉固件加载旧版BIOS引导扇区(即以旧版模式而不是UEFI引导),则它必须切换回实模式。

在这种情况下,IDK会保持加载多少固件;它可能会切换到保护模式,并在处理int 10h和其他旧版PC BIOS调用时返回保护模式,以访问实模式代码无法覆盖的内存。