现代PC视频硬件是否在硬件中支持VGA文本模式,或者BIOS是否模拟了它(使用系统管理模式)?


10

当您在物理线性地址的VGA文本(模式03)帧缓冲器中存储一个字节(例如(0x31))到VGA文本(模式03)时,在以16位旧式BIOS MBR模式引导的现代PC硬件上究竟发生了什么? 针对该区域MTRR设置为UC 商店有多慢在一台Kaby Lake iGPU笔记本电脑上进行的实验测试表明,WC上的clflushopt与VGA内存的UC大致相同。但是,如果没有clflushopt,存储到WC内存中的内存永远不会离开CPU,也根本不会更新屏幕,运行速度非常快)'1'B8000mov [es:di], eaxmov

如果不是每个商店的SMI,是否有任何方法可以在用户空间中的WB内存块上近似估算此成本,以进行性能实验而无需实际重新进入实模式?(例如,使用BSS页面作为假装的帧缓冲区,该缓冲区实际上不会显示在任何地方)。

下次刷新时,相应的字形出现在屏幕上,但是硬件扫描真的从VRAM(或iGPU的DRAM)中读取ASCII字符并动态映射到位图字形吗?还是每个存储上都有某个软件拦截或每个vblank拦截一次,以便真正的硬件仅需要处理位图帧缓冲区?


众所周知,传统BIOS引导使用系统管理模式(SMM)将USB kbd /鼠标模拟为PS / 2设备。我想知道它是否也用于VGA文本模式帧缓冲区。我认为它用于VGA的I /模式的设置O端口,但它是合理的,文本的framebuffer可以通过硬件来支持。但是,大多数计算机将所有时间都花在图形模式上,因此抛弃对文本模式的硬件支持似乎是厂商可能想要做的事情。(OTOH 该博客建议自制的Verilog VGA控制器可以相当简单地实现文本模式。)

我对在Intel Skylake中使用iGPU的系统特别感兴趣,但对Intel和AMD的早期/以后iGPU以及新旧的离散GPU感兴趣。

(包括AMD和NVidia以外的供应商;有些Skylake主板具有PCI插槽,而不是PCIe。如果现代GPU固件驱动程序确实模拟文本模式,则大概是一些旧的PCI视频卡具有硬件VGA文本模式。也许这样的卡可能使商店仅是PCI事务而不是SMI。)

我自己的台式机是华硕Z170 Pro游戏主板中的i7-6700k,没有附加卡,只有在DVI-D输出上具有1920x1200显示器的iGPU。我不知道Kaby Lake i5-7300HQ系统的详细信息@Eldan仅在CPU型号上进行测试。


从2011年起发现了Phoenix BIOS的专利US20120159520,它 使用uefi模拟旧版视频。他们不要求视频硬件供应商同时提供UEFI 本机16位实模式选项ROM驱动程序,而是提出了实模式VGA驱动程序(int 10h功能等),该驱动程序通过SMM挂钩调用供应商提供的UEFI视频驱动程序。

摘要
通用视频选项ROM将视频服务请求通知通用视频SMM驱动程序。可以使用软件系统管理中断(SMI)执行此类通知。收到通知后,通用视频SMM驱动程序会将对视频服务的请求通知第三方UEFI视频驱动程序。第三方视频驱动程序向操作系统提供请求的视频服务。以此方式,第三方UEFI图形驱动程序可以支持多种操作系统,即使不是本机支持UEFI显示协议的操作系统。

许多描述涵盖了处理int 10h呼叫和类似已经明显通过IVT捕获的内容,因此可以轻松地运行自定义代码,从而有意触发SMI。相关部分是它们描述的直接存储到文本模式帧缓冲区中的内容,即使对于不触发任何软件或硬件中断的代码,它们也需要工作。(除了硬件在此类商店上触发SMI之外,他们表示可以在支持的情况下使用它们。)

文字缓冲支持

[0066]在某些实施例中,应用程序可以直接操纵VGA的文本缓冲区。在这样的实施例中,通用视频SMM驱动器130以两种方式中的一种来支持这一点,这取决于硬件是否在对740 KB-768 KB存储区域(文本缓冲区所在的位置)的读/写访问时提供SMI陷阱

[0067]当SMI陷阱可用时,硬件会在每次读取或写入访问时生成一个SMI。使用SMI陷阱的陷阱地址,可以计算出确切的文本列和行,并访问虚拟文本屏幕中的相应行和列。

可替代地,为该区域启用普通存储器,并且使用周期性的SMI,通用视频SMM驱动器130扫描仿真的硬件文本缓冲器中的变化,并更新由视频驱动器维护的相应虚拟文本屏幕。在两种情况下,当检测到更改时,都会在虚拟文本屏幕上重新绘制字符。

这只是BIOS供应商的一项专利,并没有告诉我们大多数硬件的实际工作方式,或者其他供应商是否做不同的事情。但是,它的确确证存在某些硬件,这些硬件可能会在该范围内的商店中受困。(除非那只是他们决定在其专利中涵盖的一种假设可能性。)

对于我所想到的用例,仅在屏幕刷新上进行捕获要比在每个商店上进行捕获快得多,因此我很好奇哪种硬件/固件以哪种方式工作。


这个问题的动机

在第7代Intel Core上优化视频RAM中的递增ASCII十进制计数器 -将ASCII文本计数器的新数字重复存储到视频RAM的相同字节中。

我在Linux下的WB内存中的32位用户空间中测试了该代码的版本,希望通过movnti每种存储后(或偶尔在计时器中断)。但是,如果实模式引导加载程序情况不只是存储到DRAM,而是触发SMI,这是不现实的。

在WB内存中,用刷新movnti存储lock xor byte [esp], 0比用刷新快一些clflushopt。但是@Eldan报告说,在对MTRR进行编程以使其成为WC之后,VGA存储器上的速度没有任何提高。(并且与原始存储的速度相同,这表明默认情况下VGA帧缓冲区为UC。某些较早的BIOS 可以选择使VGA内存为WC,它们称为USWC =未缓存的推测写合并。)

这不是一个现实问题,所以我不是在寻找实际的解决方法。尽管有趣的是,手动将像素字节存储到VGA图形模式是否会更快。


摘要

  1. 是否有/所有真正的现代系统在每个商店上触发文本模式帧缓冲区的SMI?
  2. 如果否,是否可以使用movnti + WB内存中用户空间中的某些内容来将WC store + clflush近似于帧缓冲区?因此,我们可以轻松地perf针对性能计数器进行配置。
  3. 如果不同的BIOS和/或硬件使用不同的策略,这些策略是什么?(我不希望有任何细节,只是一个高层次的信息,例如“每个vblank SMI将VGA帧缓冲区同步到实际的硬件帧缓冲区”)
  4. 具有硬件VGA文本模式的PCIe或PCI视频卡会比集成GPU实际运行的速度更快吗?我猜想,实际的PCIe写入事务要比等待商店访问DRAM慢,但是PCIe写入要比每个商店的SMI便宜。球场/数量级比较将是有趣的。

这些问题都是高度相关的,但是如果没有我期望的重叠,我可以将其分解。


SMI没有性能计数器吗?
PRL

@prl:是的,我是这样认为的。如果我实际上编写了一个引导加载程序来对性能计数器进行编程,并在测试运行后收集并打印了它们,然后重新启动了我的桌面以运行它,那么我可以找到自己的桌面的答案。显然无法使用,perf因为尚未启动Linux。 在Linux-CentOS / Intel机器上评估SMI(系统管理中断)延迟具有有关如何计算SMI的一些详细信息。
彼得·科德斯

1
@prl:实际上,对SMI进行计数更容易:显然,这里有一个MSR,而不是性能计数器,因此只有RDMSR,MSR_SMI_COUNT=0x34而无需先编程一个计数器。
彼得·科德斯

这比我的其他想法容易得多,后者是使用第34.15节中描述的技术来检测SMI。
prl

@prl:英特尔第3卷SDM中的34.15,我想你是说什么? xem.github.io/minix86/manual/intel-x86-and-64-manual-vol3/…似乎是在描述SMM导致或参与VMEXIT的情况,而不仅仅是“裸机”上的任何旧SMM。(或者旧的BIOS引导通过SMM陷阱显示的虚假裸机...)是的,如果下次我有时间不介意重新引导桌面,我可能会编写一个16位的引导程序并在系统上进行测试...或者希望其他人感到敏锐并为我测试。
Peter Cordes

Answers:


7

是否有/所有真正的现代系统在每个商店上触发文本模式帧缓冲区的SMI?

对于视频卡,我非常怀疑。自1980年代以来,视频卡制造商就一直在硬件中内置“从char + attribute获取像素数据”逻辑(它早于VGA,自CGA以来并没有太大变化),并且只需将该逻辑剪切并粘贴到每个较新的设计中,而无需关心它。

对于根本不是视频卡的事物(例如,使用LAN的远程系统管理工具),我不知道但也不怀疑(通常它们使用特殊的管理CPU而不是主CPU,因此即使计算机是关掉”)。

如果否,是否可以使用movnti + WB内存中用户空间中的某些内容来将WC store + clflush近似于帧缓冲区?

如果您不在用户空间中,则可以更改MTTR(在所有CPU上-MTRR必须匹配,并且涉及特殊序列),以使RAM区域“未缓存”;或在页表中使用PAT(比弄乱MTRR容易得多,特别是如果您仍在使用分页,但由于仍需要缓存一致性而导致行为略有不同)。如果您位于用户空间中,那么您将不得不依靠操作系统/内核提供的任何功能,并且(取决于它是哪个操作系统)操作系统/内核可能根本不提供任何方法来执行此操作。

然而; 即使您找到一种使RAM的一部分(未缓存)的方法也不会非常相似,因为您将直接写入连接到内置于CPU的内存控制器中的内容(CPU可以非常快速地写入),而不是与PCI链路另一端的内容进行对话(这将导致更高的延迟和CPU端的较低带宽)。即使对于集成视频(最终在技术上是相同的RAM芯片),对VRAM的写入也将经历非常不同的路径(受“写模式” VGA寄存器的影响,受视频卡中的重新映射/ GART /分页的影响),位/平面掩码VGA寄存器等)。

具有硬件VGA文本模式的PCIe或PCI视频卡会比集成GPU实际运行的速度更快吗?

用于从CPU到VRAM的写入;通常,集成视频要比分立卡快得多(至少对于从CPU到线性帧缓冲区的普通写入,其中不涉及VGA的“写入逻辑”)。

对于极其粗略的估算;我希望一次写入RAM大约需要150个周期,一次写入PCI将接近1000个周期。对于SMI,我希望在SMI到达CPU之前有几百个周期的延迟,然后是CPU管道刷新的成本,然后是大约500个周期来保存CPU的状态(以及返回路径上的相同加载状态)。那么固件的代码必须先找到SMI的原因(另外几百个周期?),然后才能知道这是对VRAM的写操作,而不是其他操作。那么它就必须在考虑到帐户先前的CPU状态(CPU所处的模式,代码大小,XADD等)。接下来,它必须分析(仿真的)VGA寄存器的状态(写模式,写掩码,平面使能,控制将哪个64 KiB库映射到旧版区域,字体高度等)。基本上; 用于SMI仿真写入文本模式的帧缓冲区;我希望它花费数万个周期,然后固件的代码会忽略大量复杂性中掩盖的一个次要但重要的细节,从而导致它做错了事并且无法使用。

其他注意事项

我从2011年起发现了Phoenix BIOS的专利US20120159520,它使用uefi模拟旧版视频。

我怀疑这是否曾经实施过,因为我怀疑它能否奏效。您可以使用旧版界面进行太多(常见和晦涩)的操作(例如,检测垂直刷新,设置非标准视频模式(例如“模式X”,摆弄“显示开始”)以实现流畅的滚动和/或页面翻转,请在VBE中使用“ CRTC信息”来更改UEFI不支持且无法通过的视频计时等)。UEFI的第三方视频驱动程序。

取而代之的是,视频卡制造商花了大约10年时间才开始提供UEFI驱动程序,UEFI固件使用旧版接口来仿真UEFI服务(通常在使用UEFI服务时会中断安全启动);直到几乎所有内容都是UEFI。

我假设它(SMM)用于VGA I / O端口以进行模式设置。

我认为不是。我怀疑SMM可能与视频模糊相关的唯一事情是在早期启动期间(在OS之前)控制笔记本电脑(特别是旧笔记本电脑,尤其是“盖打开/关闭事件”)中屏幕背光的亮度。接手)。

..放弃对文本模式的硬件支持似乎是供应商可能想要做的事情

我仍然相信(最终,在已经太长的“混合BIOS + UEFI”过渡阶段之后)从硬件中删除了30多年的累积旧式混乱(A20,VGA,PS / 2,PIT,PIC等)。这是硬件制造商(Intel)一直/一直在推动采用UEFI的主要原因之一。


看起来,传统的VGA范围只是由L3缓存片根据配置寄存器中的VGA控制位直接解码为处理器图形,DMI或PCIe链接。如果没有VGA,我不确定处理器图形在该范围内的性能如何;可能它只是缓冲并将其转换为HDMI帧缓冲,然后将其发送到HDMI FDI管道,但我没有任何线索
Lewis Kelsey

谢谢,我忽略了仍然获得硬件支持的可能性,但是在系统代理中所经历的路径比直接访问内存控制器慢。这和击败内存控制器写入结合,所以我们瓶颈上的实际 DRAM吞吐量不仅仅是核心- >非核心- >内存控制器环形总线吞吐量可以解释VGA写入完全占据了运行时间和隐藏之间的差异clflushoptlock xor byte [esp], 0触发刷新。
Peter Cordes

关于必须以任何模式模拟x86来获取存储数据的观点是一个很好的观点,这确实使其难以置信,并且对于在使用VGA文本模式而不是VGA文本模式的文本控制台上滚动,其性能将是不可接受的,或者至少是值得注意的如今,Linux默认情况下都使用帧缓冲控制台执行任何操作。我忘记了即使在OS启用了多核系统上的所有内核之后,VGA文本模式也必须继续工作。
Peter Cordes

4

阅读各种现代的Intel CPU和平台控制器中枢(PCH)数据表后,似乎并没有实现必要的硬件。似乎没有任何方法可以响应VGA帧缓冲区(物理地址0xA0000-0xBFFFF)的处理器访问而生成SMI(系统管理中断)。

CPU中的内存控制器将把对VGA帧缓冲区的访问路由到集成的图形控制器,直接连接到CPU的PCI Express端口或将CPU连接到PCH的DMI接口。尽管可以单独路由VGA帧缓冲区,但这似乎仅意味着要支持单独的MDA(单色显示适配器)设备。集成的图形控制器没有详细记录,因此可以将其配置为在VGA帧缓冲区访问时生成SMI,但这似乎不太可能。无论如何,它不适用于离散图形。

英特尔PCH似乎也不支持生成SMI以响应VGA帧缓冲区访问。这将是最自然的地方,因为它已经支持生成SMI,以响应对键盘控制器,IDE控制器和其他旧设备的I / O访问。可能有一些未记录的功能可以执行此操作,但是PCH数据表中提供的可能的SMI来源列表中未包含该功能。

从理论上讲,主板制造商可以通过PCI Express端口将伪造的VGA设备连接到PCH,然后使用PCH GPIO引脚生成SMI。但是,我不确定这是否会在实践中起作用。当CPU获得SMI时,它可能会继续执行其他指令,并且在访问帧缓冲区时将无法检查CPU状态。

(类似的问题发生在SoundBlaster Live上的SoundBlaster 16仿真上。当访问旧版SoundBlaster端口时,它将生成PCI SERR#,这将在CPU上生成NMI。不幸的是,该仿真将在许多Pentium 4主板上中断,因为NMI将在下一条或后续指令上到达。)


感谢您对此进行检查。这并不排除每个vblank将VGA文本帧缓冲区同步/渲染到实际像素帧缓冲区(专利提出的另一种机制)一次的SMI处理程序,但是它确实排除了每个存储的SMI。我认为一条out指令是一种同步的并且主要是序列化的,但是UC存储仍然会通过存储缓冲区,并且在存储提交之前就已经退休了。如果out在P4上出现端口访问问题,那么普通存储将是一场灾难。
彼得·科德斯

如果系统确实使用SMI处理程序扫描文本帧缓冲区,则意味着即使cli禁用了正常中断,它也可以被WB缓存并且仍可以更新屏幕。因此这将是可检验的,我们可以用来排除或主要确认另一种可能性。
彼得·科德斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.