Как компьютеры отображают сырой низкоуровневый текст и графику

46

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

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

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

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

Doddy
источник
Это не все компьютеры, это зависит от аппаратного обеспечения дисплея. ПК на базе эволюционной линейки IBM изначально имели только текстовый режим, затем были добавлены различные графические режимы. У нас все еще есть это наследство. Старые компьютеры часто имели только текстовый режим. Другие компьютеры имели только графические режимы, такие как Amiga и оригинальные Macintoshes.
hippietrail

Ответы:

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);
}
Mehrdad
источник
Спасибо за ответ. Почему исходный код GRUB? Я не знал, что GRUB связан с самой графикой.
Додди
2
@panic Grub2 может делать некоторые интересные вещи, включая отображение изображения в качестве фона в меню выбора ОС. Не уверен насчет личинки.
Изката
@panic: Я не уверен, что это GRUB или GRUB2 (я использовал «GRUB» в общем), но они определенно могут переключиться на собственное разрешение 1600x900 на моем мониторе, так что я уверен, что у них будут вещи, которые вы можете посмотреть. (Я изучил их некоторое время назад, и я помню, что они были полезны, но я уже давно, поэтому я не помню точно, в каких файлах вы должны искать.)
Mehrdad
означает ли memory-mappedэто, что в ОЗУ имеется «буферная» область, в которой ЦП (или есть другой модуль DMA?) может считывать и записывать как от имени графической карты, так и от программы, которая пытается записать на дисплей?
n611x007
1
@naxa: Хороший вопрос ... обычно аппаратное отображение памяти означает, что в памяти есть адрес, который на самом деле не соответствует RAM. Скорее чтение или запись в него соответствует выполнению некоторых действий на некотором оборудовании. Тем не менее, я не уверен, как вы могли бы различить фактическую ОЗУ и аппаратное обеспечение, которое делает блок памяти похожим на ОЗУ ... возможно, в данном случае это фактическая ОЗУ, но у меня сложилось впечатление, что чтение и запись перехватываются аппаратно.
Мердад
25

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

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

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

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

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

Рассел Борогове
источник
Очень информативно, спасибо. Я хотел бы принять более одного!
Додди
8

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

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

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

Ƭᴇcʜιᴇ007
источник
6

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

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

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

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

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

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

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

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

m0skit0
источник