简体   繁体   English

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

[英]VESA graphics page flipping in protected mode

I am trying to figure out how the page flip in 32-bit protected mode.我想弄清楚如何在 32 位保护模式下翻页。 I run 0x4F0A and store the output table at 0x00008100 .我运行0x4F0A并将输出表存储在0x00008100 Would I be correct that the command to set the LFB location should be located at 0x00008102 ?设置 LFB 位置的命令应该位于0x00008102是否0x00008102 Knowing this is the location for that command, how would I change the location of the LFB in c then without returning to real mode?知道这是该命令的位置,我如何在不返回实模式的情况下更改 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);
}

I am trying to figure out how the page flip in 32-bit protected mode.我想弄清楚如何在 32 位保护模式下翻页。 I run 0x4F0A and store the output table at 0x00008100.我运行 0x4F0A 并将输出表存储在 0x00008100。 Would I be correct that the command to set the LFB location should be located at 0x00008102?设置 LFB 位置的命令应该位于 0x00008102 是否正确?

The 16-bit value at 0x00008102 may contain the offset (in VBE's code segment) of the "Set/Get Display Start" function. 0x00008102 处的 16 位值可能包含“设置/获取显示开始”功能的偏移量(在 VBE 的代码段中)。 If it does, you'd need to set up various descriptors in your GDT (eg "32-bit code segment for VBE", "data segment for VBE") and use a 32-bit far call to load CS with "32-bit code segment for VBE" while also loading EIP with the (zero extended to 32-bit) "value at 0x00008102" after you've loaded DS and/or ES with whatever VBE needed.如果是这样,您需要在 GDT 中设置各种描述符(例如“VBE 的 32 位代码段”、“VBE 的数据段”)并使用 32 位远调用来加载带有“32- VBE 的位代码段”,同时在您使用任何 VBE 加载 DS 和/或 ES 后,还加载带有(零扩展到 32 位)“值在 0x00008102”的 EIP。

However;然而; for VBE 3.0 (the latest version and the most likely VBE version for computers that aren't 20+ years old) the function is optional and might not exist.对于 VBE 3.0(最新版本和最有可能用于 20 年以上计算机的 VBE 版本)该功能是可选的,可能不存在。 Instead;反而; VBE 3.0 added a "VBE 3.0 protected mode interface" (which is 16-bit code for protected mode, allowing video ROM to recycle existing code and worry less about running out of space in the tiny 64 KiB ROM). VBE 3.0 增加了“VBE 3.0 保护模式接口”(保护模式的 16 位代码,允许视频 ROM 回收现有代码,不用担心 64 KiB ROM 的空间不足)。

Of course for very old video cards (before VBE 2.0) the "VBE 3.0 protected mode interface" will never exist.当然,对于非常旧的显卡(VBE 2.0 之前),“VBE 3.0 保护模式接口”将永远不会存在。

This means that to support "all VBE" you have to use either real mode, virtual8086 mode or an interpreter for VBE 1.2 and older;这意味着要支持“所有 VBE”,您必须使用实模式、virtual8086 模式或 VBE 1.2 及更早版本的解释器; and may use the same "real mode, virtual8086 mode or an interpreter" for both VBE 2.0 and VBE 3.0 (to avoid extra hassle dealing with both "VBE 2.0 protected mode interface" and "VBE 3.0 protected mode interface").并且可以对 VBE 2.0 和 VBE 3.0 使用相同的“实模式、virtual8086 模式或解释器”(以避免处理“VBE 2.0 保护模式接口”和“VBE 3.0 保护模式接口”的额外麻烦)。

There are also other problems;还有其他问题; mainly, VBE doesn't provide any "IRQ on vertical sync", if you use the "set display start on vertical sync" option (in VBE's "Set/Get Display Start" function) it will waste a huge amount of CPU time polling to detect if/when vertical sync has started, and if you don't do that you'll end up with tearing (and avoiding tearing is the entire point of doing "page flip" in the first place).主要是VBE不提供任何“垂直同步IRQ”,如果你使用“设置垂直同步显示开始”选项(在VBE的“设置/获取显示开始”功能中)它会浪费大量的CPU时间轮询检测垂直同步是否/何时开始,如果你不这样做,你最终会撕裂(避免撕裂是首先进行“翻页”的重点)。 It is possible to fix that by using a timer to emulate "IRQ on vertical sync" (specifically, call "Set/Get Display Start" when the timer expires and then use how long it takes "Set/Get Display Start" to return to adjust when the timer will expire next, so that you know the timer will expire just before the vertical sync happens).可以通过使用计时器来模拟“垂直同步上的 IRQ”来解决这个问题(具体来说,当计时器到期时调用“设置/获取显示开始”,然后使用“设置/获取显示开始”需要多长时间才能返回到调整下一次计时器何时到期,以便您知道计时器将在垂直同步发生之前到期)。

The other thing to worry about is bugs in the VBE's code.另一个需要担心的是 VBE 代码中的错误。 In general frequently used code (eg to set a video mode) is more heavily tested and less likely to have bugs, and rarely used code (eg to set the display start) is more likely to have bugs (and crash, and ruin everything).一般来说,经常使用的代码(例如设置视频模式)经过更严格的测试并且不太可能有错误,而很少使用的代码(例如设置显示开始)更有可能有错误(和崩溃,并破坏一切) . I'm not sure, but I think it is possible to mitigate some of the risk by isolating VBE's code (executed via. either "VBE protected mode interface") inside a "CPL=3 sandbox" (like a process).我不确定,但我认为可以通过将 VBE 的代码(通过“VBE 保护模式接口”执行)隔离在“CPL=3 沙箱”(如进程)中来减轻一些风险。

Of course for modern computers (with UEFI) VBE itself doesn't exist at all;当然,对于现代计算机(使用 UEFI)来说,VBE 本身根本不存在; and UEFI doesn't provide any alternative way to do page flipping.并且 UEFI 不提供任何替代方法来进行翻页。 This means that (if you use VBE and page flipping) it will be hard to port the OS to hardware that is still relevant later.这意味着(如果您使用 VBE 和翻页)将很难将操作系统移植到以后仍然相关的硬件上。

For all of these reason;由于所有这些原因; it's better to use "boot loader sets up a frame buffer using whatever firmware provides, and kernel/OS only uses the frame buffer and nothing else (until/unless it starts native video driver/s)";最好使用“引导加载程序使用固件提供的任何内容设置帧缓冲区,内核/操作系统仅使用帧缓冲区而不使用其他任何内容(直到/除非它启动本机视频驱动程序)”; and avoid a huge amount of work for something that (at best) can't work well.并避免为(充其量)无法正常工作的事情进行大量工作。

Knowing this is the location for that command, how would I change the location of the LFB in c then without returning to real mode?知道这是该命令的位置,我如何在不返回实模式的情况下更改 c 中 LFB 的位置?

Most C compilers don't support segmentation;大多数 C 编译器不支持分段; which means that you'd have to use an assembly language stub to load VBE's segments (including a "far call" that loads VBE's code segment) and restore your normal segments afterwards.这意味着您必须使用汇编语言存根来加载 VBE 的段(包括加载 VBE 代码段的“远调用”),然后恢复正常的段。

You'd also need to worry about what happens if an IRQ occurs while VBE's code is running.您还需要担心如果在 VBE 的代码运行时发生 IRQ 会发生什么。 You really don't want to disable IRQs (because there's no guarantee that VBE's function will be fast and no guarantee that disabling IRQs wile VBE's code is running won't ruin IRQ latency for all of your device drivers, especially for the "waste lots of CPU time while waiting for vertical sync" case);你真的不想禁用 IRQ(因为不能保证 VBE 的功能会很快,也不能保证在 VBE 的代码运行时禁用 IRQ 不会破坏所有设备驱动程序的 IRQ 延迟,特别是对于“浪费批次”等待垂直同步时的 CPU 时间”情况); so all interrupt handlers will want to be able to handle interrupting VBE's code.所以所有的中断处理程序都希望能够处理中断 VBE 的代码。

Apart from that;除此之外; you can think of "display start" as the offset in the LFB where the first pixel sent to the monitor will be (note that "display start" can also be used for smooth scrolling - eg move "display start" one row of pixels only to scroll vertically one pixel at a time).您可以将“显示开始”视为发送到显示器的第一个像素所在的 LFB 中的偏移量(请注意,“显示开始”也可用于平滑滚动 - 例如,仅将“显示开始”移动一行像素一次垂直滚动一个像素)。 You'll also need some safeguards (eg fall back to "no page flipping" if the LFB isn't large enough for 2 frames, based on the "TotalMemory (in 64 KiB chunks)" field of the structure returned by VBE's "Return Controller Information" and the vertical resolution and "bytesPerLine" taken from the structure returned by VBE's "Get Mode Information").您还需要一些保护措施(例如,如果 LFB 不足以容纳 2 帧,则回退到“不翻页”,基于 VBE 的“Return”返回的结构的“TotalMemory(64 KiB 块)”字段控制器信息”以及从 VBE 的“获取模式信息”返回的结构中获取的垂直分辨率和“bytesPerLine”)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM