切换到 VESA/VBE?

Switch to VESA/VBE?

所以,我目前正在研究 OS,我陷入了一个非常愚蠢的境地:切换到 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

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

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

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

不要使用 "fixed mode numbers"(例如模式 0x0118),因为该模式可能不受支持,如果支持,它可能与您预期的完全不同,因为 "fixed mode numbers" 大约在 25 年前被 VBE 版本 2 弃用。

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

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

b1) 使用"VBE function 0x00 (Return VBE Controller Information)" 获取有效视频模式编号的列表。如果此功能不起作用,请退回到 "ancient VGA only" 或放弃(假设没有显卡,即使有)。

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

b3) Advanced/optional 步骤。在创建可能的视频模式列表时;您可能希望与来自显示器的信息进行交叉引用,并尝试过滤掉显示器不支持的视频模式。请注意,由 VBE 编辑的视频模式 return 可能是显卡支持的,但显示器不支持;所以除非你检查你不能保证任何东西(除了 640 * 480 视频模式)将实际工作。警告:解析 EDID 是可怕的(主要是因为他们试图用最少的比特打包尽可能多的东西,针对不同的视频时序使用几种不同的格式,其中一些需要您自己的查找表);并尝试将 "mode timing"(由监视器报告,包括刷新率等)与 "video mode"(由 VBE 使用,没有任何 timing/refresh 信息)匹配并不是一门精确的科学。

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

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

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

  • 如果它是 8 位索引视频模式,请使用 "VBE function 0x08 (Set DAC Palette Format)" 然后 "VBE function 0x09 (Set Palette Data)" 以 known/sane 方式设置调色板(我更喜欢“2位红色、3 位绿色、2 位蓝色”调色板)。注意:您要强制视频卡的 DAC 进入默认的“每通道 6 位”模式,因为并非始终支持更好的每通道 8 位,这避免了使用 2 段不同的代码来构造数据的麻烦对于 DAC。

  • 从您之前从 "VBE function 0x01 (Return Mode Information)" 获得的信息中提取详细信息(水平和垂直分辨率、帧缓冲区地址、像素格式、像素行之间的字节等)这样您就可以将此信息传递给您绘图的任何代码。

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

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