首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >VESA图形页面在保护模式下翻转

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

Stack Overflow用户
提问于 2020-09-15 09:23:03
回答 1查看 197关注 0票数 0

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

代码语言:javascript
复制
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);
}
EN

回答 1

Stack Overflow用户

发布于 2020-09-15 14:55:40

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

0x00008102处的16位值可以包含"Set/Get Display Start“函数的偏移量(在VBE的代码段中)。如果是这样的话,你需要在你的GDT中设置不同的描述符(例如“VBE的32位代码段”,“VBE的数据段”),并使用一个32位的远调用来加载CS“VBE的32位代码段”,同时在你加载DS和/或ES需要的任何VBE之后,也用(零扩展到32位) "value at 0x00008102“加载EIP。

但是,对于VBE3.0(最新版本,也是最有可能的VBE版本,适用于不是20+年限的计算机),该功能是可选的,可能不存在。取而代之的是,VBE3.0增加了“VBE3.0保护模式接口”(这是保护模式的16位代码,允许视频只读存储器回收现有代码,更少地担心在微小的64 KiB只读存储器中空间不足)。

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

这意味着要支持“所有VBE”,你必须使用实模式、virtual8086模式或用于VBE1.2和更早版本的解释器;并且可以对VBE2.0和VBE3.0使用相同的“实模式、virtual8086模式或解释器”(以避免处理“VBE2.0保护模式接口”和“VBE3.0保护模式接口”的额外麻烦)。

还有其他问题;主要是,VBE没有提供任何“垂直同步的IRQ”,如果你使用“设置垂直同步的显示开始”选项(在VBE的"Set/Get Display Start“功能中),它将浪费大量的CPU时间轮询来检测是否/何时垂直同步已经开始,如果你不这样做,你将以撕裂结束(避免撕裂是做”翻页“的首要目的)。可以通过使用计时器来模拟“垂直同步时的IRQ”来解决这一问题(具体地说,当计时器到期时调用"Set/Get Display Start“,然后使用"Set/Get Display Start”返回的时间来调整计时器下一次到期的时间,这样您就知道计时器将在垂直同步发生之前到期)。

另一件要担心的事情是VBE的代码中的bug。通常,频繁使用的代码(例如,设置视频模式)测试较重,不太可能有错误,而很少使用的代码(例如,设置显示开始)更有可能有错误(并崩溃,并破坏一切)。我不确定,但我认为可以通过隔离VBE的代码(通过.或者是"CPL=3沙箱“内的"VBE保护模式接口”(就像一个进程)。

当然,对于现代计算机(使用UEFI),VBE本身根本不存在;并且UEFI不提供任何可选的翻页方法。这意味着(如果你使用VBE和翻页)很难将操作系统移植到以后仍然相关的硬件上。

由于所有这些原因,最好使用“引导加载程序使用任何固件设置帧缓冲区,内核/OS只使用帧缓冲区而不使用其他(直到/除非它启动本机视频驱动程序/s)”;并避免为(充其量)不能很好地工作的事情做大量的工作。

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

的位置呢?

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

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

除此之外,您可以将“显示开始”视为LFB中发送到监视器的第一个像素的偏移量(请注意,“显示开始”也可用于平滑滚动-例如,移动“显示开始”一行像素,以便一次垂直滚动一个像素)。你还需要一些保护措施(例如,如果LFB不够大到2帧,基于VBE的"Return Controller Information“返回的结构的"TotalMemory (in 64 KiB chunks)”字段,以及从VBE的"Get Mode Information“返回的结构中获取的垂直分辨率和"bytesPerLine”),则返回到“无翻页”。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63893771

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档