In diesem Artikel
- Ein Framebuffer ist eine Anzeige-Schnittstelle
- Warum die finale Fassung wirklich auf dem Telefon läuft
- Auflösung, Pixelformat und Zeilenabstand
- Ein kleines Rechenbeispiel ohne Gerätzugriff
- Die eigene Linux-Anzeige nur ansehen
- Echte Tasten brauchen eine passende Ereignisauswertung
- Ton und dauerhafter Start sind eigene Aufgaben
- Projekt und Quellen
Ein Cisco CP-9951 sieht nach einem Bürotelefon aus. Im Inneren arbeitet jedoch ein ARM-Linux-System. Mein DOOM-Projekt nutzt dessen lokale Anzeige und echte Telefontasten: Die finale v.666-Fassung läuft auf dem Telefon selbst und ist auch nach einem kabelfreien Neustart dokumentiert.
Die ganze Entwicklung steht in Field Note 7 im Computermuseum. Hier geht es um den technischen Kern für Einsteiger: Was ist ein Framebuffer, wie findet ein Pixel seinen Speicherplatz und weshalb gehören Eingabe, Ton und Startmechanismus zusätzlich zum Port?
Ein Framebuffer ist eine Anzeige-Schnittstelle
Stell dir einen Speicherbereich vor, dessen Werte als Bildpunkte auf dem Bildschirm erscheinen. Über die Linux-fbdev-Schnittstelle kann ein Programm Informationen über eine solche Fläche abfragen und ihre Bilddaten zugänglich machen.
Ein Gerät wie /dev/fb1 ist kein PNG und keine fertige Fensteroberfläche. Das Programm muss Geometrie, Speicherlayout und Pixelformat kennen. Eine Zahl allein, etwa „32 Bit“, sagt noch nicht, an welcher Stelle die roten oder blauen Farbanteile stehen.
Moderne Linux-Desktops verwenden vielfach DRM/KMS und einen Compositor. Ein sichtbares /dev/fb0 kann dort eine Kompatibilitätsschicht sein. Der alte eingebettete Cisco-Aufbau ist deshalb kein universelles Rezept für jede heutige Grafikkarte.
Warum die finale Fassung wirklich auf dem Telefon läuft
Die Projektgeschichte unterscheidet mehrere Entwicklungsstufen. Anfangs lief das Spiel auf Cthulhu und das Telefon empfing einen Stream. Später kam eine Eingabebrücke hinzu. Diese Zwischenstände hatten andere Datenwege als der finale native Port.
Im finalen Aufbau führt die ARM-CPU des Telefons den Spielprozess aus. Die Ausgabe geht an /dev/fb1, die lokale Eingabe kommt über /dev/input/keypad0. Das Projekt dokumentiert MontaVista Linux mit einem 2.6.18-Kernel auf ARMv6. Diese konkrete Plattform bestimmte Toolchain und Systemvoraussetzungen.
| Aufgabe | Finaler Projektbezug |
|---|---|
| Spielberechnung | ARM-Prozess auf dem CP-9951 |
| Bildausgabe | Lokaler Framebuffer /dev/fb1 |
| Steuerung | Lokale Raven-Keypad-Ereignisse |
| Start | Applications → Doom über einen lokalen Endpunkt |
Ein Foto des Displays allein könnte einen Stream nicht ausschließen. Die beschriebenen Laufzeitpfade und der dokumentierte Offline-Kaltstart liefern hier die wichtigere Unterscheidung.
Auflösung, Pixelformat und Zeilenabstand
Für einen Framebuffer braucht ein Renderer unter anderem sichtbare Breite und Höhe, Bits pro Pixel sowie den Abstand zwischen zwei Bildzeilen. Dieser Zeilenabstand wird oft als stride beziehungsweise pitch bezeichnet; im fbdev-Festdatenblock heißt er line_length.
Eine Zeile kann am Ende Padding enthalten. Daher ist Breite × Bytes pro Pixel nicht immer der tatsächliche Abstand zur nächsten Zeile. Bei gepackten Pixeln lässt sich ein Byte-Offset grundsätzlich aus Zeilenabstand und horizontaler Pixelposition berechnen; zusätzliche virtuelle Offsets und das wirkliche Format müssen berücksichtigt werden.
Die Linux-Schnittstelle bietet dafür unter anderem FBIOGET_FSCREENINFO und FBIOGET_VSCREENINFO. Das sind Abfragen für feste und veränderliche Anzeigeinformationen. Ein Port sollte seine Annahmen gegen die tatsächlichen Antworten prüfen.
Ein kleines Rechenbeispiel ohne Gerätzugriff
Die nächsten Werte sind erfundene Übungswerte, keine Messwerte des Cisco. Das Beispiel verwendet acht Pixel pro Zeile, vier Bytes pro Pixel und einen Zeilenabstand von 40 Bytes. Es schreibt nichts in ein Anzeigegerät.
Speichere die Datei als framebuffer-offset.py in einem eigenen Übungsordner:
width = 8
height = 6
bytes_per_pixel = 4
stride = 40
x, y = 3, 2
assert 0 <= x < width and 0 <= y < height
assert stride >= width * bytes_per_pixel
offset = y * stride + x * bytes_per_pixel
print(offset)
Führe sie aus:
python3 framebuffer-offset.py
Das Ergebnis ist 92. Ohne Padding wäre die Berechnung für diese Position anders. Ändere nur x oder y und beobachte den Unterschied. Das Beispiel erklärt Adressierung in einem einfachen gepackten Layout; es enthält noch keine Farbumwandlung, Geräteabfrage oder sichere Speicherabbildung.
Die eigene Linux-Anzeige nur ansehen
Auf einem eigenen Linux-Rechner kannst du zunächst lesen, ob fbdev-Geräte registriert sind:
cat /proc/fb
Falls fb0 und die entsprechenden sysfs-Dateien existieren, lassen sich zusätzliche Angaben lesen:
cat /sys/class/graphics/fb0/virtual_size
cat /sys/class/graphics/fb0/bits_per_pixel
Fehlende Dateien sind auf manchen Systemen erwartbar. Diese Angaben allein reichen außerdem nicht für einen korrekten Renderer. Schreibe für die Übung nicht mit dd, cat oder einem fremden Testprogramm direkt nach /dev/fb…: Damit würdest du die aktive Anzeige verändern und kennst das Speicherlayout noch nicht.
Echte Tasten brauchen eine passende Ereignisauswertung
Das Cisco-Projekt dokumentiert lokale 16-Byte-Ereignisse für den 32-Bit-Aufbau. Sie enthalten Zeitfelder, Typ, Tastencode und Wert. Die gemessenen Werte unterscheiden beispielsweise Drücken und Loslassen; Synchronisationsereignisse sind zusätzlich vorhanden.
Diese Strukturgröße gilt nicht automatisch für einen beliebigen 64-Bit-Desktop. Ein Port muss zur Ziel-ABI passen und vollständige Ereignisse lesen. Die gemessene Raven-Tastenkarte erklärt den konkreten Telefonfall.
Im finalen Spiel steuern Navigation und OK die Bewegung beziehungsweise Menüs; * feuert und # bedient Türen. Der rote Hörer beendet den Port sauber. Die Rückkehr zur Cisco-Oberfläche ist Teil des praktischen Ergebnisses, nicht bloß eine zusätzliche Taste.
Ton und dauerhafter Start sind eigene Aufgaben
Direkte Bildausgabe erzeugt noch keinen Ton. Der finale Port verwendet einen telefonlokalen Dienst-/Relay-Weg zur Cisco-Medienfunktion. Die Dokumentation beschreibt auch die Loopback-Behandlung, die den Ton nach einem kabelfreien Start ermöglicht.
Die Installation liegt persistent unter /mnt/flash2/doom-v666. Der Applications-Eintrag nutzt den lokalen Startendpunkt http://127.0.0.1:8095/launch. Eine lokale HTTP-Adresse bedeutet hier nicht, dass ein externer Webserver das Spiel berechnet. Laufzeit und Startmechanismus müssen getrennt betrachtet werden.
Installation, Rollback und Paketprüfung gehören in die Projektanleitung. Firmwarestand und Gerät sind dort entscheidend; dieser Framebuffer-Artikel ist keine pauschale Installationsanweisung für andere Telefone.
Projekt und Quellen
- Cisco-DOOM auf GitHub und v.666-Release.
- Geprüfte Projektbeschreibung.
- Projektchronologie und Tastenmessungen.
- Linux-Framebuffer-API.
Quellen geprüft am 8. Oktober 2026. Wer den Weg von Anzeige und Eingabe bis zu einem eigenen System spannend findet, kann als Nächstes meinen BoringOS-Einstieg lesen.