计算机如何显示原始的低级文本和图形

Dod*_*ddy 48 bios graphics operating-systems interrupts

我对计算机日益增长的兴趣使我提出了更深层次的问题,我们似乎不必再问这些问题了。我们的电脑,在开机,据我了解,在文本模式,其中可使用软件中断来显示一个字符0x10AH=0x0e。我们都见过著名的启动字体,无论启动什么计算机,它看起来总是一样的。

那么,计算机究竟如何在最低级别(例如,低于操作系统)输出图形?而且,当然图形不会使用软件中断一次输出一个像素,因为这听起来很慢?

是否有定义顶点、多边形、字体等基本输出的标准(例如,在 OpenGL 下,可能使用哪种 OpenGL)?让我问的是为什么操作系统在没有安装官方驱动程序的情况下通常可以正常运行?他们是怎么做到的?

如果我的假设不正确,请道歉。我将非常感谢您对这些主题的详细说明!

Rus*_*ove 26

从 IBM PC 及其克隆的早期开始,显示适配器硬件非常简单:一小块内存专用于字符单元格(标准模式下为 80x25 个字符),每个单元格有两个字节的内存. 一个字节选择了字符,另一个选择了它的“属性”——前景色和背景色加上颜色适配器的闪烁控制;单色适配器的粗体、下划线、闪烁或反向视频。视频输出硬件根据字符存储器的内容从字符形状的 ROM 表中查找像素。

为了提供一定程度的硬件独立性,字符映射的 BIOS 接口需要执行软件中断,以便在屏幕上设置单个字符单元。这是缓慢且低效的。但是,字符内存也可以由 CPU 直接寻址,因此如果您知道存在哪些硬件,则可以直接写入内存。无论哪种方式,一旦设置,角色将保留在屏幕上直到更改,您需要使用的总角色内存为 4000 字节 - 大约是今天单个 32x32 全彩色纹理的大小!

在图形模式中,情况类似;屏幕上的每个像素都与内存中的特定位置相关联,并且有一个 BIOS 设置像素接口,但高性能工作需要直接写入内存。后来的标准(如 VESA)让系统执行一些基于 BIOS 的慢速查询,以了解硬件的内存布局,然后直接使用内存。这就是操作系统可以在没有专门驱动程序的情况下显示图形的方式,尽管现代操作系统还包括每个主要 GPU 制造商硬件的基本驱动程序。即使是最新的 NVidia 卡也将支持几种不同的向后兼容模式,可能一直回到 IBM CGA。

3D 图形和 2D 之间的一个重要区别是,在 2D 中,您通常不需要每一帧都重新绘制整个屏幕。在 3D 中,如果相机移动一点点,屏幕上的每个像素都可能发生变化;在 2D 中,如果您不滚动,则大部分屏幕将保持逐帧不变,即使您正在滚动,您通常也可以进行快速的内存到内存复制,而不是重新组合整个场景。因此,这与必须为每帧的每个像素执行 INT 10h 没什么两样。

来源:我真的老了


use*_*686 25

这就是(部分)BIOS 的作用。

尽管实际计算机之间存在这种差异,但计算机的基本输入输出系统负责为操作系统提供通用接口。

也就是说,特别是对于图形,有多种绘制到屏幕的方式。您可以向 BIOS 发送 TTY 命令,但这仅限于实模式。如果你想在保护模式下绘制任何东西,你需要使用 VGA 来绘制东西。我无法比 OSDev 更好地解释它,因此请在此处查看更多信息- 但基本上,您可以从地址开始写入内存(视频内存是内存映射)以在0xB8000屏幕上绘制内容。

如果您需要比 VGA 更高的分辨率,则需要使用 VESA BIOS 扩展;我不熟悉它,但请尝试查看 GRUB 源代码以获取更多信息。

一些有用的参考资料:


如果您碰巧熟悉 D —— 我不久前写了一个小引导加载程序,它能够写入屏幕(仅文本)。如果你有兴趣,这里是代码:

align(2) struct Cell { char ch; ubyte flags = 0x07; }

@property Cell[] vram()
{ return (cast(Cell*)0xB8000)[0 .. CONSOLE_WIDTH * CONSOLE_HEIGHT]; }

void putc(char c)
{
    if (isBochs) { _outp(0xE9, c); }  // Output to the Bochs terminal!

    bool isNewline = c == '\n';
    while (cursorPos + (isNewline ? 0 : 1) > vram.length)
    {
        for (short column = CONSOLE_WIDTH - 1; column >= 0; column--)
        {
            foreach (row; 0 .. CONSOLE_HEIGHT - 1)
            {
                uint cell = column + cast(uint)row * CONSOLE_WIDTH;
                vram[cell] = vram[cell + CONSOLE_WIDTH];
            }
            vram[column + (CONSOLE_HEIGHT - 1) * CONSOLE_WIDTH].ch = ' ';
        }
        cursorPos = cast(ushort)(cursorPos - CONSOLE_WIDTH);
    }
    if (isNewline)
        cursorPos = cast(ushort)
            ((1 + cursorPos / CONSOLE_WIDTH) * CONSOLE_WIDTH);
    else vram[cursorPos++].ch = c;
}

void putc(char c, ubyte attrib) { vram[cursorPos] = Cell(c, attrib); }

void memdump(void* pMem, size_t length)
{
    foreach (i; 0 .. length)
        putc((cast(char*)pMem)[i]);
}

void clear(char clear_to = '\0', ubyte attrib = DEFAULT_ATTRIBUTES)
{
    foreach (pos; 0 .. vram.length)
        vram[pos] = Cell(clear_to, attrib);
    cursorPos = 0;
}

@property ushort cursorPos()
{
    ushort result = 0;
    _outp(0x3D4, 14);
    result += _inp(0x3D5) << 8;
    _outp(0x3D4, 15);
    result += _inp(0x3D5);
    return result;
}

@property void cursorPos(ushort position)
{
    _outp(0x3D4, 14);
    _outp(0x3D5, (position >> 8) & 0xFF);
    _outp(0x3D4, 15);
    _outp(0x3D5, position & 0xFF);
}
Run Code Online (Sandbox Code Playgroud)

  • @panic Grub2 可以做一些有趣的事情,包括在操作系统选择菜单上显示图像作为背景。不确定grub。 (2认同)
  • @naxa:好问题......通常,内存映射硬件意味着内存中有一个地址实际上并不对应于 RAM。相反,读取或写入它对应于在某些硬件上执行某些操作。也就是说,我不确定如何区分实际 RAM 和使内存块“看起来”像 RAM 的硬件...在这种情况下它可能是实际 RAM,但我的印象是读取和写入被硬件拦截。 (2认同)

Ƭᴇc*_*007 8

在引导期间,系统BIOS 会查找视频适配器。特别是,它会查找视频适配器的内置 BIOS 程序并运行它。该 BIOS 通常位于内存中的 C000h 位置。系统 BIOS 执行视频 BIOS,它初始化视频适配器。

BIOS 可以在没有操作系统或驱动程序的情况下本地显示哪些级别或模式的视频/图形,主要取决于视频 BIOS 本身。

来源/更多信息在这里- “系统启动顺序”


m0s*_*it0 6

我们的电脑,在开机时,据我所知,是文本模式,当AH=0x0e时,可以使用软件中断0x10显示一个字符

你说的是传统的 BIOS 功能。事实上,您根本不需要使用这些功能。您直接将它们写入视频内存。

计算机到底是如何在最低级别(例如,在操作系统之下)输出图形的?

这与操作系统的运行方式密切相关。不管怎样,硬件层面的操作是一样的:显卡有一个视频 RAM,它存储(简化)下一个要在屏幕上绘制的图像。您可以认为每个地址都是一个字节,代表一个像素(实际上通常每个像素需要一个以上的字节)。然后视频控制器负责将其转换为监视器理解的信号。

是否有定义顶点、多边形、字体等基本输出的标准(例如,在 OpenGL 下,可能使用哪种 OpenGL)?

AFAIK,没有。没有关于逻辑图形表示的标准。

让我问的是为什么操作系统在没有安装官方驱动程序的情况下通常可以正常运行?他们是怎么做到的?

因为它的驱动程序已经与操作系统捆绑在一起。