46

Мой постоянно растущий интерес к компьютерам заставляет меня задавать более глубокие вопросы, которые, кажется, нам больше не нужны. Наши компьютеры при загрузке, насколько я понимаю, находятся в текстовом режиме, в котором символ может отображаться с помощью программного прерывания 0x10 когда AH=0x0e. Мы все видели известный загрузочный шрифт, который всегда выглядит одинаково, независимо от того, с какого компьютера загружается.

Итак, как же компьютеры выводят графику на самом низком уровне, скажем, ниже ОС? А также, конечно, графика не выводится на пиксель за раз с использованием программных прерываний, так как это звучит очень медленно?

Существует ли стандарт, определяющий базовый вывод вершин, полигонов, шрифтов и т.д. (Например, ниже OpenGL, который может использовать OpenGL)? То, что заставляет меня спрашивать, - то, почему ОС часто может работать без официальных драйверов; Как они это делают?

Извиняюсь, если мои предположения неверны. Буду очень признателен за разработку этих тем!

4 ответа4

25

С первых дней существования IBM PC и его клонов оборудование адаптера дисплея было очень простым: небольшой блок памяти был выделен для сетки ячеек символов (80x25 символов в стандартном режиме) с двумя байтами памяти для каждой ячейки. , Один байт выбирает символ, а другой - его "атрибуты" - цвета переднего плана и фона, а также управление мерцанием для цветовых адаптеров; полужирное, подчеркнутое, мигающее или обратное видео для монохромных адаптеров. Аппаратные средства искали пиксели в таблице символьных форм ПЗУ в соответствии с содержимым символьной памяти.

Чтобы обеспечить определенную степень аппаратной независимости, интерфейс BIOS к карте символов требует выполнения программного прерывания для установки ячейки из одного символа на экране. Это было медленно и неэффективно. Тем не менее, память символов также была напрямую адресована процессором, поэтому, если вы знали, какое оборудование присутствует, вы могли бы записывать данные непосредственно в память. В любом случае, после установки символ будет отображаться на экране до тех пор, пока не изменится, а общая память символов, с которой вам нужно было работать, составляла 4000 байт - размером с одну полноцветную текстуру 32x32!

В графических режимах ситуация была аналогичной; каждый пиксель на экране связан с определенным местом в памяти, и был установлен интерфейсный пиксель BIOS, но для высокопроизводительной работы требовалась запись непосредственно в память. Более поздние стандарты, такие как VESA, позволяли системе выполнять несколько медленных запросов на основе BIOS, чтобы узнать структуру памяти оборудования, а затем работать непосредственно с памятью. Именно так ОС может отображать графику без специального драйвера, хотя современные ОС также включают в себя базовые драйверы для оборудования каждого крупного производителя графических процессоров. Даже самая новая карта NVidia будет поддерживать несколько различных режимов обратной совместимости, вероятно, вплоть до IBM CGA.

Одним из важных отличий между 3D-графикой и 2D-графикой является то, что в 2D-графике обычно не требуется перерисовывать весь экран каждый кадр. В 3D, если камера движется даже чуть-чуть, каждый пиксель на экране может измениться; В 2D, если вы не прокручиваете, большая часть экрана будет неизменной от кадра к кадру, и даже если вы прокручиваете, вы можете обычно делать быструю копию из памяти в память вместо перекомпоновки всей сцены. Так что нет ничего лучше, чем выполнять INT 10h для каждого пикселя в каждом кадре.

Источник: я действительно старый

25

Это (частично) роль BIOS.

Базовая система ввода-вывода компьютера отвечает за обеспечение общего интерфейса для операционных систем, несмотря на такие различия между реальными компьютерами.

Тем не менее, для графики, в частности, есть разные способы рисования на экране. Есть команды TTY, которые вы можете отправить в BIOS, но это только в реальном режиме. Если вы хотите рисовать что-либо в защищенном режиме, вам нужно использовать 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);
}
8

Во время загрузки система BIOS ищет видеоадаптер. В частности, он ищет встроенный в BIOS видеоадаптер и запускает его. Этот BIOS обычно находится в ячейке C000h в памяти. Системный BIOS выполняет видео BIOS, который инициализирует видеоадаптер.

Какие уровни или режимы видео / графики BIOS может отображать изначально, без ОС или драйверов, в первую очередь зависит от самого Video BIOS.

Источник / дополнительная информация здесь - "Последовательность загрузки системы"

6

Наши компьютеры при загрузке, насколько я понимаю, находятся в текстовом режиме, в котором символ может отображаться с помощью программного прерывания 0x10, когда AH = 0x0e.

Вы говорите о старых функциях BIOS. На самом деле вам не нужно использовать такие функции вообще. Вы напрямую записываете их в видеопамять.

Как же компьютеры выводят графику на самом низком уровне, скажем, ниже ОС?

Это сильно зависит от того, как работает ОС. В любом случае, на аппаратном уровне операция такая же: у видеокарты есть видеопамять, в которой хранится (упрощается) следующее изображение, отображаемое на экране. Вы можете думать, что каждый адрес представляет собой байт, представляющий пиксель (на самом деле обычно вам требуется более одного байта на пиксель). Затем видеоконтроллер позаботится о преобразовании этого сигнала в сигнал, который понимает монитор.

Существует ли стандарт, определяющий базовый вывод вершин, полигонов, шрифтов и т.д. (Например, ниже OpenGL, который может использовать OpenGL)?

AFAIK, нет. Нет никаких стандартов о логических графических представлениях.

То, что заставляет меня спрашивать, - то, почему ОС часто может работать без официальных драйверов; Как они это делают?

Потому что у него уже есть драйверы в комплекте с ОС.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .