Como os computadores exibem texto e gráficos brutos e de baixo nível

46

Meu interesse cada vez maior por computadores está me fazendo fazer perguntas mais profundas, que parece que não precisamos mais fazer. Nossos computadores, na inicialização, tanto quanto eu o entendo, estão no modo de texto , no qual um caracter pode ser exibido usando o software 0x10quando AH=0x0e. Todos nós vimos a famosa fonte de inicialização que sempre parece a mesma, independentemente do computador que está inicializando.

Então, como diabos os computadores produzem gráficos no nível mais baixo, por exemplo, abaixo do sistema operacional? E também, certamente os gráficos não produzem um pixel de cada vez usando interrupções de software, pois isso soa muito lento?

Existe um padrão que define a saída básica de vértices, polígonos, fontes etc. (abaixo do OpenGL, por exemplo, qual OpenGL pode usar)? O que me faz perguntar é por que os SOs geralmente podem ficar bem sem os drivers oficiais instalados; como eles fizeram isso?

Desculpas se minhas suposições estão incorretas. Ficaria muito grato pela elaboração desses tópicos!

Doddy
fonte
Nem todos os computadores, depende do hardware da tela. Os PCs baseados na linha evolutiva da IBM originalmente tinham apenas o modo de texto e, em seguida, vários modos gráficos foram adicionados. Ainda temos esse legado. Os computadores mais antigos geralmente tinham apenas o modo de texto. Outros computadores tinham apenas modos gráficos, como o Amiga e os Macintoshes originais.
Hippietrail

Respostas:

25

Esse é (parcialmente) o papel do BIOS.

O sistema básico de entrada e saída do computador é responsável por fornecer uma interface comum para os sistemas operacionais, apesar das diferenças entre os computadores reais.

Dito isto, para gráficos especificamente, existem diferentes maneiras de desenhar na tela. Existem comandos TTY que você pode enviar para o BIOS, mas isso é apenas no modo real. Se você quiser desenhar qualquer coisa no modo protegido, precisará usar o VGA para desenhar. Não posso explicar melhor do que o OSDev, portanto, procure aqui mais informações - mas, basicamente, você pode gravar na memória (a memória de vídeo é mapeada na memória) começando no endereço 0xB8000para desenhar as coisas na tela.

Se você precisar de uma resolução mais alta que a VGA, precisará usar as extensões do BIOS VESA; Não estou familiarizado com isso, mas tente consultar o código-fonte do GRUB para obter mais informações.

Algumas referências úteis:


Se você está familiarizado com o D - escrevi um pequeno carregador de inicialização há algum tempo atrás, capaz de gravar na tela (somente texto). Se você estiver interessado, aqui está o 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
fonte
Obrigado pela resposta. Por que o código fonte do GRUB? Eu não sabia que o GRUB está envolvido com os gráficos em si.
Doddy
2
O @panic Grub2 pode fazer algumas coisas interessantes, incluindo exibir uma imagem como plano de fundo quando estiver no menu de seleção do SO. Não tenho certeza sobre o grub.
Izkata
@panic: Não tenho certeza se é o GRUB ou GRUB2 (usei o "GRUB" genericamente), mas eles podem definitivamente mudar para uma resolução nativa de 1600x900 no meu monitor, por isso tenho certeza de que eles terão coisas em que você possa procurar. (Eu olhei para eles um tempo atrás, e eu me lembro que eles foram úteis, mas tem sido um tempo para que eu não me lembro qual arquivo exatamente (s) você deve olhar em.)
Mehrdad
o termo memory-mappedsignifica que existe uma área de "buffer" na RAM onde a CPU (ou existe outra unidade DMA?) pode ler e gravar em nome da placa de vídeo e do programa que tenta gravar na tela?
N611x007
1
@ naxa: Boa pergunta ... geralmente, o hardware mapeado na memória significa que existe um endereço na memória que na verdade não corresponde à RAM. Em vez disso, ler ou escrever nele corresponde a executar alguma ação em algum hardware. Dito isso, não tenho certeza de como você poderia distinguir entre a RAM real e o hardware que faz com que um bloco de memória pareça com a RAM ... pode ser que seja a RAM real nesse caso, mas minha impressão foi de que leituras e gravações são interceptadas por hardware.
Mehrdad 8/09/2013
25

Desde os primórdios do IBM PC e de seus clones, o hardware do adaptador de vídeo era muito simples: um pequeno bloco de memória era dedicado a uma grade de células de caracteres (80x25 caracteres no modo padrão), com dois bytes de memória para cada célula . Um byte selecionou o caractere e o outro selecionou seus "atributos" - cores de primeiro e segundo plano, além de controle de piscada para adaptadores de cores; vídeo em negrito, sublinhado, piscando ou reverso para adaptadores monocromáticos. O hardware procurou pixels em uma tabela ROM de formas de caracteres de acordo com o conteúdo da memória de caracteres.

Para oferecer um certo grau de independência de hardware, a interface do BIOS para o mapa de caracteres exigia a execução de uma interrupção do software para definir uma célula de caractere na tela. Isso foi lento e ineficiente. No entanto, a memória de caracteres também era endereçável diretamente pela CPU; portanto, se você soubesse qual hardware estava presente, poderia escrever diretamente na memória. De qualquer maneira, uma vez definido, o caractere permaneceria na tela até ser alterado, e a memória total de caracteres com a qual você precisava trabalhar era de 4000 bytes - aproximadamente o tamanho de uma única textura de 32x32 em cores!

Nos modos gráficos, a situação era semelhante; cada pixel na tela está associado a um local específico na memória, e havia uma interface de conjunto de pixels do BIOS, mas o trabalho de alto desempenho exigia a gravação direta na memória. Padrões posteriores, como o VESA, permitem que o sistema faça algumas consultas lentas com base no BIOS para aprender o layout da memória do hardware e, em seguida, trabalhar diretamente com a memória. É assim que um sistema operacional pode exibir gráficos sem um driver especializado, embora os sistemas operacionais modernos também incluam drivers básicos para o hardware de todos os principais fabricantes de GPUs. Até a mais nova placa NVidia suporta vários modos de compatibilidade com versões anteriores, provavelmente desde o IBM CGA.

Uma diferença importante entre gráficos 3D e 2D é que, em 2D, geralmente não é necessário redesenhar a tela inteira a cada quadro. Em 3D, se a câmera se mover um pouquinho, todos os pixels na tela poderão mudar; em 2D, se você não estiver rolando, a maior parte da tela permanecerá inalterada quadro a quadro, e mesmo se estiver rolando, geralmente é possível fazer uma cópia rápida de memória em memória em vez de recompor a cena inteira. Portanto, não é nada como ter que executar INT 10h para cada pixel em cada quadro.

Fonte: Eu sou muito velho

Russell Borogove
fonte
Muito informativo, obrigado. Eu gostaria de poder aceitar mais de um!
Doddy
8

Durante a inicialização, o BIOS do sistema procura o adaptador de vídeo. Em particular, ele procura o programa BIOS embutido no adaptador de vídeo e o executa. Este BIOS é normalmente encontrado no local C000h na memória. O BIOS do sistema executa o BIOS de vídeo , que inicializa o adaptador de vídeo.

Quais níveis ou modos de vídeo / gráficos o BIOS pode exibir nativamente, sem um SO ou drivers, depende principalmente do próprio BIOS de vídeo.

Fonte / Mais informações aqui - "Sequência de inicialização do sistema"

Ƭᴇcʜιᴇ007
fonte
6

Nossos computadores, na inicialização, até onde eu entendi, estão no modo de texto, no qual um caractere pode ser exibido usando o software interrompe 0x10 quando AH = 0x0e

Você está falando sobre funções herdadas do BIOS. Na verdade, você não precisa usar essas funções. Você os escreve diretamente na memória de vídeo.

como diabos os computadores produzem gráficos no nível mais baixo, digamos, abaixo do sistema operacional?

Isso tem a ver com a maneira como o sistema operacional opera. De qualquer forma, a operação é a mesma no nível do hardware: a placa de vídeo possui uma RAM de vídeo, que armazena (simplificando) a próxima imagem a ser desenhada na tela. Você pode pensar que cada endereço é um byte que representa um pixel (na verdade geralmente você precisa de mais de um byte por pixel). Em seguida, o controlador de vídeo se encarrega de traduzir isso em um sinal que o monitor entende.

Existe um padrão que define a saída básica de vértices, polígonos, fontes etc. (abaixo do OpenGL, por exemplo, qual OpenGL pode usar)?

AFAIK, não. Não há padrões sobre representações gráficas lógicas.

O que me faz perguntar é por que os SOs geralmente podem ficar bem sem os drivers oficiais instalados; como eles fizeram isso?

Porque ele já possui drivers incluídos no sistema operacional.

m0skit0
fonte