我最近对编写一个简单的内核感兴趣。我在互联网上进行了一些搜索并遇到了OSDev Wiki。我设置了基本的内核(经过一些挫折,交叉编译器)。现在我想更进一步:我想开始为单个像素写入值。我遇到的唯一令人满意和可理解的答案是Wiki上的那个,Drawing in Protected Mode。我想使用提供的功能,但仍然无法理解我需要传递的参数作为参数。下面是我正在使用的函数的代码,我无法理解第一个参数需要传递的内容。我需要一些内存缓冲区(类似于用于文本的terminal_buffer)吗?
/* only valid for 800x600x32bpp */
static void putpixel(unsigned char* screen, int x,int y, int color) {
unsigned where = x*4 + y*3200;
screen[where] = color & 255; // BLUE
screen[where + 1] = (color >> 8) & 255; // GREEN
screen[where + 2] = (color >> 16) & 255; // RED
}
这可能是一个愚蠢的问题,因为我对OS开发很新。
提前致谢,
的javax
顺便说一句:我正在做x86代码。我还看到了this问题,并尝试用C ++编写它。此代码编译,但如果我调用该函数,则OS拒绝启动。在返回GRUB菜单屏幕之前,它只进入此阶段:the stage it boots to。但是,如果我能找到替代解决方案,这可能就不足为重了。这是另一种选择:
void setPixel () {
asm ("mov %ah, 0x0C");
asm ("mov %al, 0x13");
asm ("int $0x10");
asm ("mov %ah, 0x0C");
asm ("mov %bh, 0");
asm ("mov %dx, 5");
asm ("mov %cx, 5");
asm ("mov %al, 0x04");
asm ("int $0x10");
}
答案 0 :(得分:0)
我没有在保护模式下编码,但如果我在保护模式下正确记住,中断的处理方式不同,需要一些桥接才能访问,所以第二个中断示例代码不起作用(但我可能错了)。尝试谷歌如何从保护模式访问 VGA / VESA / VBE BIOS 功能。
第一个示例假设您在系统中存在 VESA / VBE 卡,并在远程指针屏幕上从 LFB 模式配置为视频模式800x600x32bpp
。我也从未做过这样的事情,但是当你设置 VGA / VESA 的视频模式时,它默认会切换到页面模式。
因此,如果您只是切换到800x600x32bpp
而不是页面模式(本机)。因此, VRAM 在实际模式下映射到0xA000:0000 - 0xA000:FFFF
。当您处于保护模式时,您需要以某种方式将其转换/映射到32位空间。
另外,当您使用32位模式时,您应该使用DWORD
颜色并使用单个操作存储像素(例如stosd
或DWORD *screen
并且不使用4*
来自地址计算where = x + y*800;
)。
所以你有两个选择:
LFB线性帧缓冲区
VESA / VBE gfx卡可以使用 LFB (我认为从版本1.2或2.0),这意味着您可以映射 VRAM 以线性方式指定内存空间。因此,在这种情况下,screen
是您将 VRAM 映射到的地址。关于如何操作,您应该参考 VESA 和 VBE 文档。如果没有正确配置,您的示例将永远不会有效。
页面模式
在页面模式下,您只能访问 VRAM 的64 KByte
。对于320x200x8bpp
以上的视频模式,这还不够,您需要选择要使用的64 KB内存段。这叫做分页。看这里#2 VGA GFX mode还有实模式 VESA 示例。我们的想法是从坐标计算地址和页面。在你的情况下(对于BYTE指针):
BYTE far screen=(BYTE far*)0xA0000000;
DWORD adr = 4*x + 4*800*y;
DWORD page = adr>>16; adr &= 0xFFFF;
VESApage(page);
screen[adr]=r; adr++;
screen[adr]=g; adr++;
screen[adr]=b;
或:
DWORD far screen=(DWORD far*)0xA0000000;
DWORD adr = x + 800*y;
DWORD page = adr>>14; adr &= 0x3FFF;
VESApage(page);
screen[adr]=rgba;
VESApage()
来源位于上面的链接中。因此,在这种情况下,screen
是固定的VRAM地址,但正如我之前提到的,为了在保护模式下工作,这可能会发生很大变化。您还应该查看Graphics mode in assembly 8086
由于您提供的链接确认我怀疑您无法直接从受保护模式访问 BIOS 功能,因此我会选择 LFB ,因为它更快,而不是在视频模式配置后,需要进一步 BIOS 功能访问。因此,您必须在切换到保护模式之前设置视频模式!!!。
希望参数color,x,y
对您来说很清楚。如果你不知道BYTE
和DWORD
是什么,它们是unsigned int
的8和32位宽。