简体   繁体   English

VESA 在尝试填满屏幕时跳过视频内存的“块”

[英]VESA skipping “blocks” of video memory when trying to fill the screen

I'm developing a simple OS' kernel and I am trying to make a working video library so I can use it later.我正在开发一个简单的操作系统内核,我正在尝试制作一个有效的视频库,以便以后可以使用它。 (VBE version 3.0, 1920 * 1080px, 32bpp). (VBE 3.0 版,1920 * 1080 像素,32bpp)。
I wrote a pixel plotting function in C which seems to be working fine:我在 C 中编写了一个像素绘图函数,它似乎工作正常:

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

Then I tried to fill the whole screen using this function and two for loops:然后我尝试使用这个函数和两个for循环来填充整个屏幕:

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

This is the result that I ended up with so far:这是我到目前为止得到的结果:

在此处输入图片说明


(I even tried to fill each single byte in the video memory with 0xFF to make sure that I'm not altering other pixels or stuff :P... and, uhh.. I got the same result.) (我什至试图用 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

Any idea why this doesn't work?知道为什么这不起作用吗? Did I access memory the wrong way?我是否以错误的方式访问内存?


EDIT:编辑:

The MODEINFOBLOCK structure: 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]; };

You probably didn't enable the A20 gate.您可能没有启用 A20 门。

With A20 gate disabled, the 21st bit of physical addresses is ignored/masked to zero (to help emulate an old 8086 CPU where there were only 20 address lines).禁用 A20 门后,物理地址的第 21 位将被忽略/屏蔽为零(以帮助模拟只有 20 个地址线的旧 8086 CPU)。 The result is that when you try to fill the frame buffer;结果是当你尝试填充帧缓冲区时; the first 1 MiB of pixels works, then the second 1 MiB of pixels overwrites the first 1 MiB of pixels (leaving an unfilled black band), then the third 1 MiB of pixels works but gets overwritten by the fourth 1 MiB of pixels, and so on.第一个 1 MiB 像素有效,然后第二个 1 MiB 像素覆盖前 1 MiB 像素(留下未填充的黑色带),然后第三个 1 MiB 像素有效但被第四个 1 MiB 像素覆盖,并且很快。

This creates "filled and not filled" horizontal bands.这会创建“填充和未填充”水平带。 If you do the math, ("1 MiB / 1920 / 4") you'd expect the horizontal bands to be about 136.5 pixels tall;如果您进行数学计算,(“1 MiB / 1920 / 4”)您会期望水平带的高度约为 136.5 像素; so there'd be slightly more than 7 bands ("1000 / 136.5");所以会有略多于 7 个频段(“1000 / 136.5”); which is what you're getting.这就是你得到的。

To enable the A20 gate;启用 A20 门; see https://wiki.osdev.org/A20_Line .https://wiki.osdev.org/A20_Line

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

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