AFAIK,BIOS大小限制为段大小(0xFFFF)。但是,如今许多BIOS都超过了64KB,通常超过10MB。它怎么做到的?
答案 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-0xfffff
或0xe0000-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处的窗口更大。
可以根据需要将窗口的大小设置为大(与其他系统设备兼容),但是有一个陷阱(实际上是两个)。
固件如何为20MiB? 如今,固件主要由四个组件组成:
以上讨论的窗口仅适用于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调用时返回保护模式,以访问实模式代码无法覆盖的内存。