uEFI: Graphics Output Protocol (GOP)
« | 23 Jan 2022 | »Im klassischen PC BIOS aus den alten 16-Bit Zeiten hatten wir den Interrupt 10h (INT 0x10) um den Grafikmodus zu ändern.
Mit uEFI wurde diese antiquierte 16-Bit Technik modernisiert und somit steht mit dem Graphics Output Protocol (GOP) eine C-API der Firmware bereit, um Pixelgrafiken auf den Monitor zu bekommen.
In den glorreichen Zeiten, in denen “die coolen Jungs” ihr eigenes OS bauen
wollten, starteten viele mit dem 512 Bytes großen Bootsektor-Code, wechselten
per int 10h
in den Grafikmodus und zeichneten ein paar verwegene
“You are hacked” Zeichen auf den Schirm.
Das ganze auf eine Diskette gespielt und ins Laufwerk gelegt, ließ Papa am Abend erblassen, wenn er seine Excel-Zeitlisten in Windows 95 befüllen wollte.
Nun sterben langsam auch die letzten Firmware-Varianten aus, die noch ein
BIOS CSM (Compatibility Support Module) enthalten.
Die Zukunft heißt (seit 10 bis 15 Jahren): uEFI.
Das GOP Protokoll
Über die GOP GUID (9042a9de-23dc-4a38-96fb7aded080516a
) erlangt man von
BootServices->LocateProtocol
einen Pointer zum
EFI_GRAPHICS_OUTPUT_PROTOCOL
Interface.
Dieses stellt die Methoden QueryMode()
, SetMode()
und Blt()
bereit,
sowie einen Pointer namens Mode
zu den Daten des aktuellen Modus.
Mode->MaxMode
gibt die Anzahl der verfügbaren Grafik-Modi zurück und nun
kann man per Schleife von 0 bis MaxMode
zählen und diesen Parameter als ID
an QueryMode()
übergeben um Infos zum dahinter liegenden Grafikmodus zu
erhalten.
Das wären:
- Pixel-Höhe und -Breite des Grafikmodus
- Art des Pixelformats
- RGBX: 32 bit Wert mit dem Inhalt rot, grün, blau + unbenutztes Füllbyte
- BGRX: 32 bit Wert mit dem Inhalt blau, grün, rot + unbenutztes Füllbyte
- BitMask: In einer zusätzlichen Struktur wird beschrieben, welche Bits in einem 32-bit Pixel den Farbkanälen rot, grün und blau zugeordnet sind.
Üblicherweise startet die Auflistung beim alten VGA-Standard 640 x 480 und wird dann zunehmend größer.
Mit der Funktion SetMode()
kann dann in den Grafikmodus wechseln, wenn man die
gewünschte Index-ID
einsetzt.
Am interessantesten ist dann die Funktion Blt()
, die Pixelpufferinhalte in die
Video-Hardware übertragen kann.
Das funktioniert sogar in beide Richtungen, man kann also Pixel aus dem eigenen
Buffer in die Anzeige transferieren oder die angezeigten Pixel in den eigenen
Puffer kopieren lassen.
Man kann also ein Breite * Höhe
großes Feld von uint32_t
Werten anlegen
und dann die Pixel je nach Modus setzen und das gesamte Frame per Blt()
anzeigen lassen.
Fazit
Das tolle an UEFI
ist, dass die C-API bereits mitgeliefert wird und somit kann
man mit wenigen Zeilen einen Bootloader mit grafischen Menü zaubern.
Früher hätte man im BIOS dann per Assembler auf die Hardware-Adressen
zugreifen müssen und eben genau dafür schrieben sich viele Entwickler ihre eigene
Blt()
Funktion.
Schön zu sehen, dass das nun obsolet und die neue Methode standardisiert ist.
Nun existiert im GATE Framework auch eine Framebuffer-Implementierung, die direkt unter EFI ausführbar ist und Grafiken auf den Monitor zeichnen kann.
Und erneut bin ich erstaunt, wie einfach es ist, den PC “ohne Betriebssystem” zu betreiben.