VESA图形页面在保护模式下翻转

问题描述

我试图弄清楚页面如何在32位保护模式下翻转。我运行0x4F0A并将输出表存储在0x00008100处。设置LFB位置的命令应该位于0x00008102上是否正确?知道这是该命令的位置后,如何在不返回实模式的情况下更改c中LFB的位置?

void main() {
    char vmem_back_buffer0[3932160];
    char vmem_back_buffer1[3932160];
    char* prot_mode_desc  = (char*)0x00008102;

    /* ... code to file those buffers with data is removed for brevity ... */

    // Here I change the LFB location to vmem_back_buffer0
    // Here I change the LFB location to vmem_back_buffer1

    while (TRUE);
}

解决方法

我试图弄清楚页面如何在32位保护模式下翻转。我运行0x4F0A并将输出表存储在0x00008100。我是否正确,用于设置LFB位置的命令应该位于0x00008102?

0x00008102处的16位值可能包含“设置/获取显示开始”功能的偏移量(在VBE的代码段中)。如果是这样,则需要在GDT中设置各种描述符(例如,“ VBE的32位代码段”,“ VBE的数据段”),并使用32位远方调用来加载带有“ 32-在为DS和/或ES加载了所需的任何VBE之后,还同时加载了EIP(零扩展至32位)“ 0x00008102处的值”,同时为VBE提供了位代码段。

但是;对于VBE 3.0(未使用20年以上的计算机的最新版本和最可能的VBE版本),此功能是可选的,可能不存在。代替; VBE 3.0添加了“ VBE 3.0保护模式接口”(这是保护模式的16位代码,使视频ROM可以回收现有代码,而不必担心64 KiB ROM中的空间不足)。

当然,对于非常旧的视频卡(在VBE 2.0之前),“ VBE 3.0保护模式接口”将永远不存在。

这意味着要支持“所有VBE”,您必须使用实模式,virtual8086模式或VBE 1.2及更早版本的解释器;并且可能对VBE 2.0和VBE 3.0使用相同的“实模式,virtual8086模式或解释器”(以避免在处理“ VBE 2.0保护模式接口”和“ VBE 3.0保护模式接口”时更加麻烦)。

还有其他问题;通常,VBE不提供任何“垂直同步上的IRQ”,如果使用“在垂直同步上设置显示开始”选项(在VBE的“设置/获取显示开始”功能中),则会浪费大量的CPU时间轮询检测垂直同步是否开始/何时开始,如果不这样做,最终会导致撕裂(首先避免“撕裂”是进行“页面翻转”的全部目的)。可以通过使用计时器来模拟“垂直同步上的IRQ”来解决此问题(具体而言,在计时器到期时调用“设置/获取显示开始”,然后使用多长时间才能返回到“设置/获取显示开始”)调整计时器下一次到期的时间,以便您知道计时器即将在垂直同步发生之前到期。

需要担心的另一件事是VBE代码中的错误。通常,经常使用的代码(例如,设置视频模式)经过更严格的测试,并且不太可能出现错误,而很少使用的代码(例如,设置显示开始)则更有可能出现错误(并且崩溃并破坏一切) 。我不确定,但是我认为可以通过在“ CPL = 3沙箱”(如过程)中隔离VBE代码(通过“ VBE保护模式接口”执行)来减轻某些风险。 >

当然,对于现代计算机(带有UEFI),VBE本身根本不存在。而且UEFI没有提供任何其他方式来进行页面翻转。这意味着(如果您使用VBE和页面翻转)将很难将OS移植到以后仍然有用的硬件上。

由于所有这些原因;最好使用“引导加载程序使用任何提供的固件来设置帧缓冲区,并且内核/ OS仅使用帧缓冲区,而没有其他功能(直到/除非它启动本机视频驱动程序)”;并避免为(最好)无法正常工作的事情做大量的工作。

知道这是该命令的位置后,如何在不返回实模式的情况下更改c中LFB的位置?

大多数C编译器不支持分段。这意味着您必须使用汇编语言存根来加载VBE的段(包括加载VBE的代码段的“远调用”),然后再恢复正常段。

您还需要担心,如果在运行VBE的代码时出现IRQ,会发生什么情况。您真的不想禁用IRQ(因为不能保证VBE的功能会很快,也不能保证在运行VBE的代码时禁用IRQ不会破坏所有设备驱动程序的IRQ延迟,尤其是对于“浪费很多”的驱动程序等待垂直同步的情况下的CPU时间”);因此所有中断处理程序都希望能够处理中断VBE的代码。

除此之外;您可以将“显示开始”看作是发送到显示器的第一个像素所在的LFB中的偏移量(请注意,“显示开始”也可以用于平滑滚动-例如,仅将“显示开始”移动一行像素一次垂直滚动一个像素)。您还需要一些保护措施(例如,如果LFB不足以容纳2帧,则退回到“无页面翻转”),这是基于VBE返回的结构的“ TotalMemory(以64 KiB块为单位)”字段控制器信息”以及垂直分辨率和“ bytesPerLine”(取自VBE的“获取模式信息”所返回的结构)。