【问题标题】:VESA skipping "blocks" of video memory when trying to fill the screenVESA 在尝试填满屏幕时跳过视频内存的“块”
【发布时间】:2021-09-04 03:41:19
【问题描述】:

我正在开发一个简单的操作系统内核,并且我正在尝试制作一个可以工作的视频库,以便以后可以使用它。 (VBE 版本 3.0,1920 * 1080px,32bpp)。
我在 C 中编写了一个像素绘图函数,似乎工作正常:

void putPixelRGB(struct MODEINFOBLOCK mib, short x, short y, int color) {
   int *pos = (char *)mib.framebuffer + x * 4 + y * 7680;
       *pos = color;
}

然后我尝试使用这个函数和两个for 循环来填充整个屏幕:

for(int i = 0; i < 1920; i++) {
   for(int j = 0; j < 1080; j++) {
      putPixelRGB(mib, i, j, 0xFFFFFF);
   }
}

这是我到目前为止得到的结果:




(我什至尝试用 0xFF 填充视频内存中的每个单个字节,以确保我没有改变其他像素或东西:P...而且,嗯.. 我得到了相同的结果。)

dloop:
   mov byte[eax], 0xFF           ;eax contains the address of the FB memory.
   inc eax
   cmp eax, 829440               ;829440 = 1920 * 1080 * 4
   jg done
   jmp dloop

done:
   hlt

知道为什么这不起作用吗?我是否以错误的方式访问内存?


编辑:

MODEINFOBLOCK 结构:

struct MODEINFOBLOCK {
    int attributes;
    char windowA, windowB;
    int granularity;
    int windowSize;
    int segmentA, segmentB;
    long winFuncPtr;
    int pitch;      

    int resolutionX, resolutionY;
    char wChar, yChar, planes, bpp, banks;
    char memoryModel, bankSize, imagePages;
    char reserved0;

    char readMask, redPosition;           
    char greenMask, greenPosition; 
    char blueMask, bluePosition;
    char reservedMask, reservedPosition;
    char directColorAttributes;

    char* framebuffer;                     
    long offScreenMemOff;
    int offScreenMemSize;
    char  reserved1 [206];
};

【问题讨论】:

  • modeinfo 说什么?另外,这不是minimal reproducible example。无论如何,很难找到具有正常工作 VBE3 的真正显卡。
  • @Jester 我会更新的。
  • 我知道结构,我想知道当前模式的值。

标签: c assembly x86 kernel vesa


【解决方案1】:

您可能没有启用 A20 门。

在禁用 A20 门的情况下,物理地址的第 21 位将被忽略/屏蔽为零(以帮助模拟只有 20 条地址线的旧 8086 CPU)。结果是当您尝试填充帧缓冲区时;第一个 1 MiB 像素有效,然后第二个 1 MiB 像素覆盖前 1 MiB 像素(留下未填充的黑色带),然后第三个 1 MiB 像素有效,但被第四个 1 MiB 像素覆盖,并且以此类推。

这会创建“填充和未填充”的水平带。如果你算一下,(“1 MiB / 1920 / 4”)你会期望水平带大约 136.5 像素高;所以会有略多于 7 个波段(“1000 / 136.5”);这就是你得到的。

启用 A20 门;见https://wiki.osdev.org/A20_Line

【讨论】:

  • 非常感谢!我不知何故忘记在我的引导加载程序中调用启用 A20 门的“函数”。
  • 有趣的事实:我已经花了大约 2 个月的时间来弄清楚它出了什么问题。
  • @MARSHMALLOW:“80x86 PC”(主要是英特尔)正在推动 UEFI 有一些很好的理由 - 向后兼容性在一段时间内是好的(直到你有像 1980 年代的“A20”这样的丑陋黑客) 40 年后融入硬件;-)。
猜你喜欢
  • 1970-01-01
  • 2021-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多