Cómo las computadoras muestran texto y gráficos en bruto de bajo nivel

46

Mi creciente interés en las computadoras me está haciendo hacer preguntas más profundas, que parece que ya no tenemos que hacer más. Nuestras computadoras, en el arranque, por lo que yo entiendo, están en modo de texto , en el que se puede mostrar un personaje usando la interrupción del software 0x10cuando AH=0x0e. Todos hemos visto la famosa fuente de arranque que siempre se ve igual, independientemente de qué computadora se esté iniciando.

Entonces, ¿cómo demonios las computadoras generan gráficos en el nivel más bajo, digamos, debajo del sistema operativo? Y también, ¿seguramente los gráficos no se emiten un píxel a la vez usando interrupciones de software, ya que eso suena muy lento?

¿Existe un estándar que defina la salida básica de vértices, polígonos, fuentes, etc. (debajo de OpenGL, por ejemplo, qué OpenGL podría usar)? Lo que me hace preguntar es por qué el sistema operativo a menudo puede estar bien sin controladores oficiales instalados; ¿Cómo lo hacen?

Disculpas si mis suposiciones son incorrectas. ¡Estaría muy agradecido por la elaboración de estos temas!

Doddy
fuente
No todas las computadoras dependen del hardware de la pantalla. Las PC basadas en la línea evolutiva de IBM originalmente solo tenían modo de texto, luego se agregaron varios modos de gráficos. Todavía tenemos ese legado. Las computadoras más antiguas a menudo solo tenían modo de texto. Otras computadoras solo tenían modos gráficos, como el Amiga y los Macintosh originales.
hippietrail

Respuestas:

25

Esa es (en parte) la función del BIOS.

El sistema básico de entrada y salida de la computadora es responsable de proporcionar una interfaz común a los sistemas operativos, a pesar de las diferencias entre las computadoras reales.

Dicho esto, específicamente para gráficos, hay diferentes formas de dibujar en la pantalla. Hay comandos TTY que puede enviar al BIOS, pero eso es solo en modo real. Si desea dibujar algo en modo protegido, debe usar VGA para dibujar cosas. No puedo explicarlo mejor que OSDev, así que mire aquí para obtener más información , pero básicamente, puede escribir en la memoria (la memoria de video está asignada en la memoria) comenzando en la dirección 0xB8000para dibujar cosas en la pantalla.

Si necesita una resolución más alta que VGA, debe usar las extensiones de BIOS VESA; No estoy familiarizado con él, pero intente mirar el código fuente de GRUB para obtener más información.

Algunas referencias útiles:


Si está familiarizado con D, escribí un pequeño gestor de arranque hace un tiempo que podía escribir en la pantalla (solo texto). Si estás interesado, aquí está el código:

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
fuente
Gracias por la respuesta. ¿Por qué el código fuente GRUB? No sabía que GRUB está involucrado con los gráficos en sí.
Doddy
2
@panic Grub2 puede hacer algunas cosas interesantes, como mostrar una imagen como fondo cuando está en el menú de selección del sistema operativo. No estoy seguro acerca de la comida.
Izkata
@panic: No estoy seguro de si es GRUB o GRUB2 (usé "GRUB" genéricamente), pero definitivamente pueden cambiar a una resolución nativa de 1600x900 en mi monitor, así que estoy seguro de que tendrían cosas en las que puedes mirar. (Los examiné hace un tiempo, y recuerdo que fueron útiles, pero he pasado un tiempo, así que no recuerdo exactamente qué archivo (s) debe buscar.)
Mehrdad
¿significa el término memory-mappedque hay un área de "búfer" en la RAM donde la CPU (o hay otra unidad DMA?) puede leer y escribir en nombre de la tarjeta gráfica y el programa que intenta escribir en la pantalla?
n611x007
1
@naxa: Buena pregunta ... por lo general, el hardware mapeado en memoria significa que hay una dirección en la memoria que en realidad no corresponde a la RAM. Más bien, leerlo o escribirlo corresponde a realizar alguna acción en algún hardware. Dicho esto, no estoy seguro de cómo distinguir entre la RAM real y el hardware que hace que un bloque de memoria se vea como RAM ... podría ser que se trata de RAM real en este caso, pero mi impresión fue que las lecturas y escrituras son interceptadas por hardware
Mehrdad
25

Desde los primeros días de la PC de IBM y sus clones, el hardware del adaptador de pantalla era muy simple: un pequeño bloque de memoria estaba dedicado a una cuadrícula de celdas de caracteres (80x25 caracteres en el modo estándar), con dos bytes de memoria para cada celda . Un byte seleccionó el carácter y el otro seleccionó sus "atributos": colores de primer plano y de fondo más control de parpadeo para adaptadores de color; video en negrita, subrayado, parpadeante o inverso para adaptadores monocromos. El hardware buscó píxeles de una tabla ROM de formas de caracteres de acuerdo con el contenido de la memoria de caracteres.

Para ofrecer un cierto grado de independencia del hardware, la interfaz del BIOS para el mapa de caracteres requería que se ejecutara una interrupción de software para establecer una celda de caracteres única en la pantalla. Esto fue lento e ineficiente. Sin embargo, la memoria de caracteres también era directamente direccionable por la CPU, por lo que si sabía qué hardware estaba presente, podría escribir directamente en la memoria. De cualquier manera, una vez configurado, el carácter permanecería en la pantalla hasta que se cambiara, y la memoria total de caracteres con la que tenía que trabajar era de 4000 bytes, ¡aproximadamente del tamaño de una sola textura a todo color de 32x32!

En los modos gráficos, la situación era similar; cada píxel en la pantalla está asociado con una ubicación particular en la memoria, y había una interfaz BIOS configurada en píxeles, pero el trabajo de alto rendimiento requería escribir directamente en la memoria. Los estándares posteriores como VESA permiten que el sistema realice algunas consultas lentas basadas en BIOS para conocer el diseño de la memoria del hardware y luego trabajar directamente con la memoria. Así es como un sistema operativo puede mostrar gráficos sin un controlador especializado, aunque los sistemas operativos modernos también incluyen controladores básicos para el hardware de los principales fabricantes de GPU. Incluso la nueva tarjeta NVidia admitirá varios modos diferentes de compatibilidad con versiones anteriores, probablemente hasta IBM CGA.

Una diferencia importante entre los gráficos 3D y 2D es que en 2D generalmente no es necesario volver a dibujar la pantalla completa en cada fotograma. En 3D, si la cámara se mueve incluso un poquito, cada píxel en la pantalla puede cambiar; en 2D, si no se desplaza, la mayor parte de la pantalla no cambiará de cuadro a cuadro, e incluso si se desplaza, generalmente puede hacer una copia rápida de memoria a memoria en lugar de recomponer toda la escena. Por lo tanto, no es nada como tener que ejecutar INT 10h por cada píxel en cada cuadro.

Fuente: soy muy viejo

Russell Borogove
fuente
Muy informativo, gracias. ¡Ojalá pudiera aceptar más de uno!
Doddy
8

Durante el arranque, el BIOS del sistema busca el adaptador de video. En particular, busca el programa BIOS incorporado del adaptador de video y lo ejecuta. Este BIOS normalmente se encuentra en la ubicación C000h en la memoria. El BIOS del sistema ejecuta el BIOS de video , que inicializa el adaptador de video.

Los niveles o modos de video / gráficos que el BIOS puede mostrar de forma nativa, sin un SO o controladores, dependen principalmente del Video BIOS en sí.

Fuente / Más información aquí - "Secuencia de arranque del sistema"

Ƭᴇcʜιᴇ007
fuente
6

Nuestras computadoras, en el arranque, por lo que yo entiendo, están en modo texto, en el que se puede mostrar un personaje usando el software de interrupción 0x10 cuando AH = 0x0e

Estás hablando de las funciones de BIOS heredadas. De hecho, no necesita usar tales funciones en absoluto. Los escribes directamente en la memoria de video.

¿Cómo demonios las computadoras generan gráficos en el nivel más bajo, digamos, debajo del sistema operativo?

Esto tiene mucho que ver con el funcionamiento del sistema operativo. De todos modos, la operación es la misma a nivel de hardware: la tarjeta de video tiene una RAM de video, que almacena (simplifica) la siguiente imagen que se dibujará en la pantalla. Puede pensar que cada dirección es un byte que representa un píxel (en realidad, generalmente necesita más de un byte por píxel). Luego, el controlador de video se encarga de traducir esto en una señal que el monitor comprende.

¿Existe un estándar que defina la salida básica de vértices, polígonos, fuentes, etc. (debajo de OpenGL, por ejemplo, qué OpenGL podría usar)?

AFAIK, no. No hay estándares sobre representaciones gráficas lógicas.

Lo que me hace preguntar es por qué el sistema operativo a menudo puede estar bien sin controladores oficiales instalados; ¿Cómo lo hacen?

Porque ya tiene controladores incluidos en el sistema operativo.

m0skit0
fuente