首页 > 解决方案 > 现代 PC 视频硬件是否支持硬件中的 VGA 文本模式,或者 BIOS 是否模拟它(使用系统管理模式)?

问题描述

您将诸如'1'(0x31) 之类的字节存储到物理线性地址的VGA 文本(模式 03)帧缓冲区中时,在以 16 位传统 BIOS MBR 模式启动的现代 PC 硬件上到底会发生什么B8000该地区的MTRR设置为 UC的商店有多慢?mov [es:di], eax在一台 Kaby Lake iGPU 笔记本电脑上进行的实验测试表明,WC 上的 clflushopt 与 VGA 内存的 UC 速度大致相同。但没有 clflushopt,mov存储到 WC 内存永远不会离开 CPU,也不会更新屏幕,运行速度非常快.)

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

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


众所周知,传统 BIOS 引导使用系统管理模式 (SMM)将 USB kbd/鼠标模拟为 PS/2 设备。我想知道它是否也用于 VGA 文本模式帧缓冲区。我假设它用于VGA I/O 端口以进行模式设置,但硬件可以支持文本帧缓冲区是合理的。但是,大多数计算机都将所有时间都花在图形模式下,因此供应商可能想要放弃对文本模式的硬件支持。(OTOH这个博客建议自制的verilog VGA控制器可以相当简单地实现文本模式。)

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

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

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


从 2011 年发现了Phoenix BIOS 的专利 US20120159520, Emulating legacy video using 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 代英特尔酷睿视频 RAM 中递增的 ASCII 十进制计数器- 将 ASCII 文本计数器的新数字重复存储到相同的几个字节的视频 RAM 中。

我在 WB 内存上测试了 Linux 下 32 位用户空间中的代码版本,希望movnti在每次存储之后(或者可能偶尔在定时器中断)。但是,如果实模式引导加载程序的情况不仅仅是存储到 DRAM,而是触发 SMI,那么这是不现实的。

在 WB 内存上,movnti使用 a 刷新存储lock xor byte [esp], 0比使用 刷新要快一些clflushopt。但是@Eldan 报告说,在将 MTRR 编程为 WC 后,那些使用 VGA 内存的速度并没有提高。(并且与原始进行正常存储的速度相同,表明默认情况下 VGA 帧缓冲区是 UC。一些较旧的 BIOS可以选择使 VGA 内存 WC,他们称之为 USWC = Uncached Speculative Write Combining。)

这不是现实世界的问题,所以我不是在寻找实际的解决方法;虽然知道手动将像素字节存储到 VGA 图形模式是否会更快,但会很有趣。


概括

  1. 是否有任何/所有真正的现代系统在每个存储到文本模式帧缓冲区时触发 SMI?
  2. 如果不是,我们可以在 WB 内存上使用 movnti + 用户空间中的某物来将 WC store+clflush 近似为帧缓冲区吗?因此,我们可以轻松地使用perf性能计数器进行概要分析。
  3. 如果不同的 BIOS 和/或硬件使用不同的策略,那么这些策略是什么?(我不想要细节,只是像“SMI every vblank to sync the VGA framebuffer to the actual hardware framebuffer”之类的高级别的)
  4. 具有硬件 VGA 文本模式的 PCIe 或 PCI 视频卡会比集成 GPU 的实际运行速度更快吗?我猜测实际的 PCIe 写入事务会比等待存储击中 DRAM 慢,但 PCIe 写入会比每个存储上的 SMI 便宜。一个大概/数量级的比较会很有趣。

这些问题都是高度相关的,但如果没有像我预期的那么多重叠,我可以把它分开。

标签: performanceassemblyx86-16biosvga

解决方案


是否有任何/所有真正的现代系统在每个存储到文本模式帧缓冲区时触发 SMI?

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

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

如果不是,我们可以在 WB 内存上使用 movnti + 用户空间中的某物来将 WC store+clflush 近似为帧缓冲区吗?

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

然而; 即使您找到一种方法使 RAM (一个区域)不缓存,它仍然不会非常相似,因为您将直接写入连接到 CPU 内置内存控制器的东西(该 CPU 可以非常快速地写入) 而不是与 PCI 链路另一端的某物交谈(这将具有更高的延迟和来自 CPU 端的更低带宽)。即使对于集成视频(最终在技术上是相同的 RAM 芯片)写入 VRAM 也会通过非常不同的路径(受制于视频卡中的重新映射/GART/分页,受“写入模式”VGA 寄存器的影响,受位/平面掩码 VGA 寄存器等)。

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

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

对于极其粗略的大致估计;我希望对 RAM 的单次写入大约为 150 个周期,对 PCI 的单次写入接近 1000 个周期。对于 SMI,我预计 SMI 到达 CPU 之前有几百个延迟周期,然后是 CPU 管道刷新的成本,然后是大约 500 个周期来保存 CPU 的状态(以及返回路径上的相同加载状态);那么固件的代码必须找到 SMI 的原因(另外几百个周期?),然后才能知道这是对 VRAM 的写入,而不是别的什么;然后它必须检查保存的 CPU 状态并找到并解码进行写入的指令(因为它不知道正在写入什么数据,如果它是字节/字/双字写入等)同时考虑考虑以前的 CPU 状态(CPU 处于哪种模式,代码大小,XADD, ETC)。接下来,它必须分析(模拟)VGA 寄存器的状态(写入模式、写入掩码、平面启用、任何控制将哪个 64 KiB 银行映射到遗留区域、字体高度等)。基本上; 用于写入文本模式帧缓冲区的 SMI 仿真;我预计固件代码需要数万个周期才能忽略隐藏在大量复杂性中的一个次要但重要的细节,导致它做错事并无法使用。

其他注意事项

我从 2011 年发现了 Phoenix BIOS 的专利 US20120159520,Emulating legacy video using uefi。

我怀疑这曾经被实施过,因为我怀疑它永远不会奏效。您可以使用传统界面做太多(常见和晦涩)的事情(例如检测垂直刷新,设置非标准视频模式,如“模式 X”,摆弄“显示开始”以实现平滑滚动和/或翻页,在 VBE 中使用“CRTC 信息”来更改 UEFI 不支持且无法通过的视频计时等)。UEFI 的第三方视频驱动程序。

取而代之的是,显卡制造商在大约 10 年的时间里都没有费心提供 UEFI 驱动程序,并且 UEFI 固件使用旧接口来模拟 UEFI 服务(通常在他们使用时会破坏安全启动);直到几乎所有东西都是UEFI。

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

我假设不是。我怀疑 SMM 可能用于的唯一与视频模糊相关的事情是在早期启动期间(操作系统之前接手)。

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

我仍然相信(最终,在已经太长的“混合 BIOS + UEFI”过渡阶段之后)从硬件中消除 30 多年积累的遗留混乱(A20、VGA、PS/2、PIT、PIC ......)是硬件制造商(英特尔)正在/一直在推动采用 UEFI 的主要原因之一。


推荐阅读