Questo è (in parte) il ruolo del BIOS.
Il sistema di input input di base del computer è responsabile di fornire un'interfaccia comune ai sistemi operativi, nonostante tali differenze tra i computer effettivi.
Detto questo, in particolare per la grafica, ci sono diversi modi di disegnare sullo schermo. Ci sono comandi TTY che puoi inviare al BIOS, ma è solo in modalità reale. Se vuoi disegnare qualcosa in modalità protetta, devi usare VGA per disegnare le cose. Non posso spiegarlo meglio di OSDev, quindi guarda qui per maggiori informazioni - ma in sostanza, puoi scrivere in memoria (la memoria video è mappata in memoria) a partire dall'indirizzo 0xB8000
per disegnare le cose sullo schermo.
Se hai bisogno di una risoluzione superiore a VGA, devi utilizzare le estensioni del BIOS VESA; Non ne ho familiarità, ma prova a guardare il codice sorgente di GRUB per maggiori informazioni.
Alcuni riferimenti utili:
Se hai familiarità con D - Ho scritto un po 'di boot loader che era in grado di scrivere sullo schermo (solo testo). Se sei interessato, ecco il codice:
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);
}