【问题标题】:Switch to VESA/VBE?切换到 VESA/VBE?
【发布时间】:2019-07-23 12:18:56
【问题描述】:

所以,我目前正在开发一个操作系统,我陷入了一个非常愚蠢的境地:切换到 VESA/VBE

我当前的代码:

mov ax, 0x4F02
mov bx, 0x4118
int 0x10

它改变了 Qemu 的分辨率,但现在我在绘制像素时遇到了问题。像素偏移的公式为:

uint32 pixel_offset = y * pitch + (x * (bpp/8)) + framebuffer;

问题在于 bpp、pitch 和 framebuffer 应该由

mov ax, 0x4F01
int 0x10

mov ax, 0x4F00
int 0x10

首先,

mov ax, 0x4F00
int 0x10

软锁qem。即使没有,我该怎么做才能访问信息。

我想要的是一个完全用汇编 (nasm) 编写的切换到 VESA/VBE 的函数,然后我的内核可以访问一个用 c 编写的函数。

编辑:我真的不能在我的引导加载程序中包含任何 C。我需要汇编代码。

【问题讨论】:

  • 查阅参考资料。对于这两个函数,您都需要传递一个指向缓冲区的指针,您将获得那里返回的信息。
  • 小丑,你能告诉我必须把地址放在哪个寄存器里吗?因为我得到了那个缓冲区,但我不知道如何处理它!
  • see this
  • this。做你的研究。
  • Int 10h/ax=4f00h 还要求您在 ES:DI 中传递缓冲区地址。该缓冲区的一部分(前 4 个字节)必须是 VBE2 必须在调用该函数之前填写。你这样做了吗?如果您不通过 ES:DI 提供指针(实模式分段指针),谁知道数据将写入何处。我怀疑你的问题是你根本没有指定缓冲区。

标签: assembly x86 nasm osdev vesa


【解决方案1】:

不要使用“固定模式编号”(例如模式 0x0118),因为该模式可能不受支持,如果支持,它可能与您所期望的完全不同,因为“固定模式编号”是大约 25 年前被 VBE 版本 2 弃用。

考虑到这一点,基本步骤是:

a) 使用“BIOS Int x010, function 0x1A (Get Display Combination Code)”检查计算机是否支持任何类型的视频。如果它是没有任何显卡的服务器,那么设置视频模式是没有意义的。如果显卡是古老的 EGA,那么使用 VBE 也没有意义。

b1) 使用“VBE 函数 0x00(返回 VBE 控制器信息)”获取有效视频模式编号的列表。如果此功能不起作用,则退回到“仅老式VGA”或放弃(假设没有显卡,即使有)。

b2) 对于列出的每个模式编号;使用“VBE 函数 0x01(返回模式信息)”来确定模式是什么。理想情况下;你会过滤掉你的代码不支持的任何东西(例如时髦的旧“16色平面”模式,任何需要超过64 KiB的视频RAM但不支持LFB的东西,任何使用YUV而不是RGB的东西,.. .) 同时创建一个可能性列表。如果此功能不起作用,请跳过视频模式。注意:您还需要跟踪“VBE 版本号”(来自 VBE 控制器信息)并使用它来理解“VBE 函数 0x01(返回模式信息)”返回的信息(例如,确定视频卡应该返回一些仅在更高版本的 VBE 中出现的信息。

b3) 高级/可选步骤。在创建可能的视频模式列表时;您可能希望与显示器中的信息进行交叉引用,并尝试过滤掉显示器不支持的视频模式。注意VBE返回的视频模式可能显卡支持,显示器不支持;所以除非你检查你不能保证任何东西(640 * 480视频模式除外)都会真正起作用。警告:解析 EDID 很糟糕(主要是因为他们试图尽可能多地打包,针对不同的视频时序使用几种不同的格式,其中一些需要您自己的查找表);并且试图将“模式计时”(由监视器报告,包括刷新率等)与“视频模式”(由 VBE 使用,没有任何计时/刷新信息)匹配并不是一门精确的科学。

b4) 在您获得完整的视频模式列表后(根据您的操作系统支持的内容以及显示器支持的内容进行过滤);使用某种东西来确定哪种模式是“最佳”模式。这可能比您想象的要复杂得多(例如,计算显示器支持该模式的概率、显示器对视频模式的喜爱程度/它与显示器的原始分辨率的匹配程度、操作系统对性能模式的喜爱程度原因,以及视频模式与用户偏好的接近程度(如果有的话);然后进行某种计算,将所有单独的因素组合成一个视频模式的最终得分;并选择最终得分最高的视频模式)。注意:如果列表为空,请退回到可怕的旧 VGA 模式(例如 320*200 和 256 色)或放弃(假设计算机没有显卡,即使有,并继续启动)。

c) 使用“VBE function 0x02 (Set Mode)”设置选择的视频模式。如果此时出现错误,请在可能的视频模式列表中将所选视频模式标记为“borked”,然后返回“步骤 b4”。

d) 设置视频模式成功后:

  • 如果是 8 位索引视频模式,请使用“VBE 函数 0x08(设置 DAC 调色板格式)”,然后使用“VBE 函数 0x09(设置调色板数据)”以已知/合理的方式设置调色板(我更喜欢“2 位红色、3 位绿色、2 位蓝色”调色板)。注意:您想强制视频卡的 DAC 进入默认的“每通道 6 位”模式,因为并不总是支持更好的每通道 8 位,这样可以避免使用 2 段不同的代码来构建数据的麻烦用于 DAC。

  • 从您之前从“VBE 函数 0x01(返回模式信息)获得的信息中提取详细信息(水平和垂直分辨率、帧缓冲区的地址、它是哪种像素格式、像素行之间的字节数等) " 这样您就可以将此信息传递给您绘制的任何代码。

注意:为了更容易支持许多可能的视频模式(这是使代码在更多不同的计算机上工作所必需的);我建议使用“标准为您”像素格式(例如,可能是 32-bpp,ARGB)将所有绘制到 RAM 中的缓冲区,然后在将数据从 RAM 中的缓冲区复制到时将此数据转换为视频模式实际需要的内容帧缓冲区。这样一来,您绘制东西(线条、矩形、字符、窗口装饰、小猫图片等)的所有代码都只需要关心水平和垂直分辨率。

注意:您需要找到我提到的所有函数的参数和描述,并确保您了解它们所做的一切以及它们返回的所有信息。您可以在线找到所有 BIOS 功能的列表(搜索“Ralph Brown's Interrupt List”),您可以在线找到多个版本的 VBE 规范。

【讨论】:

    猜你喜欢
    • 2022-01-02
    • 1970-01-01
    • 2014-12-01
    • 2010-11-29
    • 2014-01-08
    • 1970-01-01
    • 2013-06-07
    • 2019-11-16
    • 1970-01-01
    相关资源
    最近更新 更多