当您在物理线性地址的VGA文本(模式03)帧缓冲器中存储一个字节(例如(0x31))到VGA文本(模式03)时,在以16位旧式BIOS MBR模式引导的现代PC硬件上究竟发生了什么? 将针对该区域的MTRR设置为UC 的商店有多慢? (在一台Kaby Lake iGPU笔记本电脑上进行的实验测试表明,WC上的clflushopt与VGA内存的UC大致相同。但是,如果没有clflushopt,存储到WC内存中的内存永远不会离开CPU,也根本不会更新屏幕,运行速度非常快)'1'
B8000
mov [es:di], eax
mov
如果不是每个商店的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图形模式是否会更快。
摘要
- 是否有/所有真正的现代系统在每个商店上触发文本模式帧缓冲区的SMI?
- 如果否,是否可以使用movnti + WB内存中用户空间中的某些内容来将WC store + clflush近似于帧缓冲区?因此,我们可以轻松地
perf
针对性能计数器进行配置。 - 如果不同的BIOS和/或硬件使用不同的策略,这些策略是什么?(我不希望有任何细节,只是一个高层次的信息,例如“每个vblank SMI将VGA帧缓冲区同步到实际的硬件帧缓冲区”)
- 具有硬件VGA文本模式的PCIe或PCI视频卡会比集成GPU实际运行的速度更快吗?我猜想,实际的PCIe写入事务要比等待商店访问DRAM慢,但是PCIe写入要比每个商店的SMI便宜。球场/数量级比较将是有趣的。
这些问题都是高度相关的,但是如果没有我期望的重叠,我可以将其分解。
perf
因为尚未启动Linux。 在Linux-CentOS / Intel机器上评估SMI(系统管理中断)延迟具有有关如何计算SMI的一些详细信息。
MSR_SMI_COUNT=0x34
而无需先编程一个计数器。