Previous ohne Linux auf dem Raspberry Pi 4 und 5
Previous kann auf dem Raspberry Pi 4 und dem Raspberry Pi 5 ohne Linux laufen. Der Emulator bekommt dafür eine eigene Schicht für die Bibliothek Circle, und heraus kommt je Modell ein Image, das die Firmware des Pi direkt startet. Beide liegen auf derselben SD-Karte oder demselben USB-Stick. Die Emulation selbst bleibt unverändert, die Server für NFS und NetInfo ziehen mit um, und der Ton geht wie heute an die NeXT SoundBox mini. Previously läuft im selben Image als Weboberfläche, die der Pi selbst ausliefert. Ein Update tauscht Previous und Previously gemeinsam aus, und eine Mac-App stellt die Karte zusammen. An Circle sind einzelne Änderungen nötig, die Circle angeboten werden. Der Weg führt über sechs Schritte, und nach dem zweiten startet ein NeXTcube ohne Linux bis zum Arbeitsplatz von NeXTSTEP. Der Aufwand dafür ist gross und der Gewinn klein. Abschnitt 12 empfiehlt deshalb, Linux auf dem Pi auf das Nötigste zuzuschneiden.
Inhalt
- Gegenstand
- Das Ergebnis
- Was zwischen NeXTSTEP und dem Pi liegt
- Circle als Grundlage
- Was Previous vom System braucht
- Fork und Image
- Vier Kerne und ihre Aufgaben
- Die Teile im Einzelnen
- Vorbilder
- Der Plan in sechs Schritten
- Was daraus nicht folgt
- Schluss
- Quellennachweis
Anhang
1. Gegenstand
Das Paper untersucht, ob und wie der Emulator Previous auf einem Raspberry Pi 4 und einem Raspberry Pi 5 ohne Betriebssystem laufen kann. Gemeint ist ein Aufbau, in dem Previous das einzige Programm ist, das der Pi nach seiner Firmware startet. Dazu gehört, wie dieser Aufbau eingerichtet, bedient und aktualisiert wird. Andere Boards gehören nicht dazu.
Die Grundlage sind fünf Dinge. Das erste ist der Quellcode von Previous in Revision 1858 vom 10.10.2026. Das zweite sind Quellcode und Dokumentation der Umgebungen, mit denen Programme ohne Betriebssystem auf dem Pi laufen. Das dritte sind Projekte, die andere Emulatoren bereits ohne Linux auf den Pi bringen. Das vierte ist die Firmware der NeXT SoundBox mini. Das fünfte ist Previously selbst mit seinem heutigen Admin. Alles wurde am 21.10.2026 gelesen.
Am Gerät wurde nur der Ton geprüft, am 21.10.2026 auf einem Raspberry Pi 5. Darauf lief das Beispiel 34-sounddevices von Circle, ergänzt um die Prüfung des Takts aus Abschnitt 8.3. Es spielte seinen Testton an die SoundBox mini, einen Ton um 440 Hz, dessen Tonhöhe ein zweiter Oszillator zehnmal je Sekunde um 5 Hz auf und ab bewegt1. Die SoundBox lief einmal mit ihrer Firmware vor und einmal mit der nach der Korrektur aus Abschnitt 8.3. Beurteilt wurde der Ton mit dem Ohr. Wie schnell Previous ohne Linux läuft, sagt das Paper deshalb nicht.
2. Das Ergebnis
Es geht, und die Grundlage dafür ist Circle1. Circle ist eine Umgebung in C++, mit der Programme ohne Betriebssystem auf dem Raspberry Pi laufen. Den Pi 4 führt Circle als getestet, und seit Februar 2024 unterstützt es auch den Pi 5. Auf beiden bringt es fast alles mit, was Previous vom Gerät braucht: alle vier Kerne, USB für Tastatur, Maus, Speicher und Ton, die SD-Karte mit FAT, Ethernet, einen eigenen TCP/IP-Stack und Ton über HDMI.
Previous braucht dafür eine eigene Schicht für Circle. Der Emulator hat seine Abhängigkeit vom System schon heute an wenigen Stellen gesammelt2. Fast alles, was er von SDL3 aufruft, steht im Ordner src/gui-sdl/ und in der Bildausgabe der NeXTdimension. Die Schicht für Circle tritt daneben, und ein Fork nimmt die wenigen Änderungen an Previous selbst auf. Der Prozessor, die Fliesskomma-Einheit, der DSP, der i860 und alle Geräte des NeXT bleiben, wie sie sind.
Unter dem Emulator bleibt die Firmware des Pi. Ihr Bootloader liegt im EEPROM auf der Platine und nur als fertige Binärdatei vor3. Beim Pi 5 steckt auch die Firmware selbst im EEPROM, beim Pi 4 liegt sie als Datei auf der Karte41. Sie startet jedes Programm auf dem Pi, also auch dieses.
Auch Circle braucht einzelne Änderungen. Für die Netzbrücke müssen die Ethernet-Treiber beider Modelle Frames an eine zweite Adresse annehmen. Für Plattenabbilder ab 2 GiB muss die C-Bibliothek von Circle Dateipositionen mit 64 Bit rechnen. Für den Ton prüft Circle den Takt, den die SoundBox zurückmeldet, bevor es ihn übernimmt. Alle drei Änderungen werden Circle angeboten. Die Abschnitte 4 und 8 sagen, woran das liegt.
Previously wird für das Image neu gebaut. Die Weboberfläche bleibt dieselbe, und der Pi liefert sie selbst aus. Hinter ihr steht statt des Dienstes in Python ein Teil im Image, der direkt mit dem Emulator spricht. Er kann fast alles, was der Einstellungsdialog von Previous unter F12 kann, und manches bequemer. Eingerichtet wird nicht mehr auf dem Pi, denn eine Mac-App stellt die Karte oder den USB-Stick nach Wunsch zusammen. Ein Update tauscht Previous und Previously gemeinsam aus, und der alte Stand bleibt erhalten, bis der neue sauber gestartet ist. Die Abschnitte 8.10 bis 8.12 beschreiben das. Das Netz von NeXTSTEP richtet sich wie heute von selbst ein, sobald Schritt 6 steht.
3. Was zwischen NeXTSTEP und dem Pi liegt
Heute startet der Pi Raspberry Pi OS. Die erste Konsole meldet sich automatisch an und startet den Kiosk-Compositor cage, und in ihm läuft Previous als SDL3-Programm. Den Ton gibt PipeWire an einen angesteckten Lautsprecher weiter5. Ohne Linux startet die Firmware das Image mit Previous direkt.
| Schicht | Heute | Ohne Linux |
|---|---|---|
| Boot-ROM im Chip und Bootloader im EEPROM | ja | ja |
Firmware, beim Pi 5 im EEPROM, beim Pi 4 als start4.elf auf der Karte | ja | ja |
| Arm-Stub | ja | ja |
| Linux-Kernel | ja | nein |
| systemd, die Konsole mit automatischer Anmeldung und ihre Shell | ja | nein |
| cage, die Grafik von Linux und PipeWire für den Ton | ja | nein |
| SDL3 | ja | nein |
| Circle mit der C-Bibliothek newlib | nein | ja, im selben Image wie Previous |
| Previous | ja | ja, als Fork |
Was bleibt, ist kein Betriebssystem. Die Firmware richtet Takt und Arbeitsspeicher ein und lädt das Image4. Beim Pi 5 laufen USB und Ethernet über den Baustein RP1. Die Firmware setzt ihn vor dem Start zurück6, und Circle nimmt ihn selbst in Betrieb7. Den Framebuffer liefert die Firmware dem Image auch danach noch auf Anfrage7. Beim Pi 4 hängt USB an einem eigenen Controller hinter PCIe, und auch den nimmt Circle in Betrieb1. Danach gehört der Pi dem Image. Auf seinen Kernen laufen keine anderen Prozesse und kein Compositor.
Abbildung 1 zeigt den Start ohne Linux in sechs Phasen, vom Einschalten bis zu NeXTSTEP im Netz. Jede Zeile ist ein Teil des Pi, und jedes Feld sagt, was dieser Teil in der jeweiligen Phase tut. Die Farbe sagt, wem der Schritt gehört: der Firmware, Circle, Previous oder dem emulierten NeXT. Gezeigt ist der Pi 5. Beim Pi 4 lädt der Bootloader zuerst die Firmware von der Karte, und USB und Ethernet hängen nicht am RP11.
start4.elf von der Karte, und USB und Ethernet hängen nicht am RP1.4. Circle als Grundlage
Von den Umgebungen ohne Betriebssystem bringt in der Recherche nur Circle auf beiden Modellen USB, Bild, Ton und Netz mit. Die Recherche dazu liegt im Anhang C. Dieses Paper bezieht sich auf den Zweig master von Circle mit dem Stand vom 25.09.20261. Die Bibliotheken für C und C++ kommen aus dem Begleitprojekt circle-stdlib8.
Grenzen von Circle auf dem Pi 4 und dem Pi 5
Auf dem Pi 5 legt die Firmware die Auflösung des Bildschirms fest, und config.txt ändert daran nichts. Ihr Framebuffer hat dort eine einzige Seite, deshalb kann ein bewegtes Bild reissen79.
Alle Interrupts laufen auf Kern 0, und dort läuft auch der kooperative Scheduler von Circle, der unter anderem neue USB-Geräte erkennt101.
Die Dokumentation von circle-stdlib nennt keine POSIX-Threads. std::thread gibt es nur im experimentellen Build mit libc++, und auch dort läuft es als Aufgabe des kooperativen Schedulers810. Wer mehrere Kerne nutzen will, verteilt die Arbeit selbst.
Die C-Bibliothek von Circle rechnet Dateipositionen mit 32 Bit und Vorzeichen11. Ein Programm erreicht deshalb nur die ersten 2 GiB einer Datei, gleich auf welchem Dateisystem. Das Abbild von NeXTSTEP 3.3 ist 2.012.774.400 Byte gross und passt knapp darunter5.
Speicherblöcke über 512 KB gibt Circle beim Freigeben ab Werk nicht zurück. Die Blockgrössen lassen sich beim Build so einrichten, dass auch grosse Blöcke wiederverwendet werden1.
Ein Image darf ab Werk höchstens 2 MB gross sein, mit circle-stdlib 4 MB. Die Grenze lässt sich beim Build anheben18.
Takt und Lüfter regelt unter Circle das Programm selbst. Für den Lüfter nennt Circle beim Pi 4 einen frei wählbaren GPIO und beim Pi 5 den Anschluss GPIO 451.
Den Takt, den ein USB-Gerät für den Ton zurückmeldet, übernimmt Circle ohne Prüfung. Meldet das Gerät 0, rechnet Circle daraus leere Pakete und hält an1. Abschnitt 8.3 beschreibt den Fall der SoundBox.
In den Klassen für Ton von Circle findet sich keine Umrechnung der Abtastrate. Ein Gerät bekommt Daten in der Rate, mit der es geöffnet wurde1.
5. Was Previous vom System braucht
Previous benennt die Stelle selbst, an der das System beginnt. In sechs Header-Dateien steht derselbe Satz: „These functions must be provided through host or cross-platform API.“2 Diese Dateien beschreiben Threads und Sperren, das Bild, den Ton, die Eingaben, die Tastaturbelegung und die Statuszeile unter dem Bild. Für SDL3 sind sie im Ordner src/gui-sdl/ umgesetzt.
Previous ruft 127 verschiedene Funktionen von SDL auf. Alle, die tatsächlich übersetzt werden, stehen in src/gui-sdl/ und in der Bildausgabe der NeXTdimension. Der Ordner src/gui-sdl/ umfasst rund 11.700 Zeilen, davon rund 6.500 für die Einstellungsdialoge. Previous als Ganzes umfasst rund 164.000 Zeilen. Es hat keinen JIT und keinen Assembler, und den Speicher für die emulierte Maschine holt es sich über die C-Bibliothek.
| Was | Heute | Ohne Linux | Schritt |
|---|---|---|---|
| Threads, Sperren, Zeitmessung, Warten | SDL3 | feste Kerne je Aufgabe, Spinlocks und der Zähler des Prozessors | 2 |
| Bild | SDL3 unter cage | der Framebuffer der Firmware, danach ein eigener Treiber | 2 und 3 |
| Statuszeile | SDL3 | entfällt, Previously blendet sie ohnehin aus | 2 |
| Tastatur und Maus | SDL3 | USB über Circle | 2 |
| Ton | SDL3 und PipeWire an die SoundBox mini | USB-Ton von Circle an die SoundBox mini, sonst HDMI oder beim Pi 4 der Kopfhörerausgang | 2 |
| Speicher für die emulierte Maschine | C-Bibliothek unter Linux | der Heap von Circle mit passenden Blockgrössen | 2 |
| Plattenabbilder, ROMs, Einstellungen | Dateisystem von Linux | FAT32 auf der SD-Karte, über newlib und FatFs | 2 |
| Pfade und Heimatverzeichnis | Linux | feste Pfade auf der Karte | 2 |
| Uhrzeit für die Uhr des NeXT | Linux | beim Pi 5 die Echtzeituhr, beim Pi 4 NTP über Circle | 2 und 5 |
| Ende, wenn NeXTSTEP herunterfährt | die Konsole startet Previous neu | der Pi schaltet sich aus | 2 |
| Einstellungsdialog und Fehlermeldungen | Zeichenflächen von SDL3 | bis Schritt 4 das Protokoll, danach eine kleine Zeichenschicht | 4 |
| Ethernet-Frames des NeXT | SLiRP über die Sockets von Linux | eine Brücke direkt an den Ethernet-Anschluss | 5 |
| Adresse, Router, NetInfo und NFS für NeXTSTEP | SLiRP und die Server von Previous | dieselben Server auf den Sockets von Circle, unter der Adresse des Pi | 6 |
6. Fork und Image
Der Fork kommt als phranck/previous auf GitHub. Previous selbst wird in Subversion auf SourceForge entwickelt2. Ein Zweig upstream spiegelt dessen Trunk Revision für Revision, und der Zweig main enthält die eigene Arbeit. Jede neue Revision von Previous kommt über upstream herein und wird in main zusammengeführt.
Das Image entsteht im Repository von Previously, im Ordner image/, und bindet den Fork als Submodul ein. Darin liegen die Host-Schicht, die Bildausgabe der NeXTdimension für Circle, die Hüllen um die Sockets für die Server aus Schritt 6, der Teil von Previously aus Abschnitt 8.10 und ein eigenes Makefile. Das Makefile übersetzt die Quellen von Previous ohne src/gui-sdl/ mit den Build-Regeln von Circle, und den Build von Previous selbst fasst es nicht an. BMAtariST geht mit Hatari genauso vor12. Wo Header von Previous Typen aus SDL3 erwarten, etwa host.h für Threads und Sperren, liefert image/ eine kleine Header-Datei mit genau diesen Typen. Previous und Previously sind im Image ein einziges Programm. Deshalb erscheinen sie zusammen in einem Release von Previously, unter einer Versionsnummer.
Der Fork nimmt nur Änderungen an Previous selbst auf. An bestehenden Dateien ist das die Ethernet-Emulation, die neben SLiRP und PCAP die Brücke aus Schritt 5 bekommt. Diese Änderung ist klein und allgemein genug, um sie Previous selbst anzubieten. Änderungen an Circle liegen als einzelne Patches in image/patches/, und jeder davon wird Circle angeboten.
Gebaut wird mit dem Compiler aarch64-none-elf und mit circle-stdlib als Submodul auf einem festen Stand8. Die Releases baut GitHub Actions. Zwei Werkzeuge von Previous erzeugen den Code des 68k-Prozessors, und sie laufen vorher auf dem Rechner, der baut2. Das Makefile hebt die Grenze für die Grösse des Images an und schaltet in Circle die Unterstützung mehrerer Kerne ein10. Es baut zweimal, einmal für jedes Modell. Heraus kommen kernel8-rpi4.img für den Pi 4 und kernel_2712.img für den Pi 5, und die config.txt auf der Karte wählt mit den Abschnitten [pi4] und [pi5] das passende Image16. Eine Karte startet damit auf beiden Modellen. circle-stdlib wird mit TLS gebaut, weil Updates HTTPS brauchen.
7. Vier Kerne und ihre Aufgaben
Pi 4 und Pi 5 haben je vier Kerne. Previous legt zwei Arten von Threads an, die lange laufen: einen für den Prozessor des NeXT und einen für den i860 jeder NeXTdimension2. Den Thread eines i860 beendet jeder Kaltstart und legt ihn neu an, und beim Start entsteht er vor dem Thread des Prozessors. Die Host-Schicht vergibt die Kerne deshalb nach Aufgabe und nicht nach Reihenfolge. Sie erkennt die Aufgabe am Namen, den Previous jedem Thread gibt, und ein Kern wird wieder frei, sobald sein Thread endet.
| Kern | Aufgabe |
|---|---|
| 0 | Circle mit allen Interrupts, USB und Ethernet. Dazu die Hauptschleife von Previous: Bild ausgeben, Ton nachliefern, Eingaben weiterreichen. Nach jedem Durchgang gibt sie an den Scheduler von Circle ab. Ab Schritt 6 laufen hier auch die Server für NFS und NetInfo. |
| 1 | Der Prozessor des NeXT mit Fliesskomma-Einheit, DSP und allen Geräten. |
| 2 | Der i860 der ersten NeXTdimension. |
| 3 | Der i860 einer zweiten NeXTdimension, sonst frei. |
Previously richtet höchstens eine NeXTdimension ein5. Previous selbst erlaubt drei2. Für zwei Karten reichen die Kerne. Bei drei Karten lässt die Host-Schicht alle i860 auf dem Kern des Prozessors mitlaufen, so wie Previous es auf einem Rechner mit einem einzigen Kern tut.
Was Previous an Sperren und Signalen zwischen seinen Threads braucht, deckt Circle mit Spinlocks ab, und die atomaren Operationen liefert der Compiler. Wartet ein Thread, wartet er auf seinem eigenen Kern auf den Zähler des Prozessors. Das hält niemanden auf, weil auf diesem Kern nichts anderes läuft. SLiRP und PCAP übersetzt das Image nicht, also entstehen auch ihre Threads nicht. Die Server für NFS und NetInfo starten je Verbindung einen Thread, und solche Threads legt die Host-Schicht als Aufgaben des Schedulers von Circle auf Kern 0 an.
Die Kerne des Pi 4 sind Cortex-A72, die des Pi 5 Cortex-A76107. Ob der Pi 4 einen NeXT in voller Geschwindigkeit emuliert, und ob er es mit NeXTdimension tut, zeigen die Messungen in den Schritten 2 und 3.
8. Die Teile im Einzelnen
8.1 Bild
Der NeXT zeigt 1120 mal 832 Bildpunkte bei 68 Hz2. In Schritt 2 schreibt Previous sein Bild in den Framebuffer der Firmware, mittig und ohne Skalierung. Der Bildschirm braucht dafür mindestens 832 Zeilen, und bei 1920 mal 1080 Bildpunkten bleibt ein schwarzer Rand. Auf dem Pi 5 wählt die Firmware die Auflösung, und weil ihr Framebuffer nur eine Seite hat, kann das Bild bei schneller Bewegung reissen9.
In Schritt 3 übernimmt das Image den Bildschirmtreiber von BMA800XL, zusammen mit dem Code für Ton und Grafikprozessor, auf dem er aufbaut. BMA800XL hat ihn für den Pi 4 und den Pi 5, und beide teilen sich einen Teil des Codes. Der Treiber spricht die Bildausgabe des Pi direkt an, bietet auf dem Pi 5 die Auflösungen Auto, 1920 mal 1080 und 1280 mal 720 und betreibt den Bildschirm im Takt der emulierten Maschine9. Für den NeXT sind das 68 Hz, sofern der Bildschirm sie annimmt. Das Bild der NeXTdimension erscheint auf demselben Bildschirm, und welches Bild zu sehen ist, legt wie heute previous.cfg fest.
8.2 Tastatur und Maus
Circle meldet jede Taste mit ihrem Code aus der USB-Norm für Tastaturen und die Umschalttasten getrennt davon als Bitmaske1. SDL verwendet für seine Scancodes genau diese Codes13. Der Fork nutzt deshalb die Belegung nach Scancodes, und die Tabelle, mit der Previous Scancodes in Tasten des NeXT übersetzt, gilt unverändert weiter. Tastenkürzel wie F12 erkennt Previous an den Tastencodes von SDL, und die Host-Schicht leitet sie aus denselben Codes ab.
8.3 Ton
Previous liefert Stereo mit 16 Bit bei 44,1 kHz, mit dem höherwertigen Byte zuerst2. Previously gibt den Ton heute an einen angesteckten Lautsprecher und nicht an HDMI5, und dieser Lautsprecher ist die NeXT SoundBox mini. Sie meldet sich am USB als Gerät der USB Audio Class 2.0, in Stereo, mit fest 48 kHz und wahlweise 16 oder 24 Bit. Ihr Takt ist asynchron, und sie meldet ihn über einen eigenen Endpunkt an den Rechner zurück14.
Circle bedient Geräte der USB Audio Class 1.0 und 2.0 in Stereo mit 16 oder 24 Bit. Für den Pi 4 nennt Circle das ausdrücklich. Für den Pi 5 ist derselbe Code eingeschaltet, und das Beispiel von Circle, das unter anderem über USB spielt, ist als auf dem Pi 5 lauffähig markiert1. Den zurückgemeldeten Takt wertet Circle aus und passt die Grösse jedes Pakets daran an1. Damit bleibt die SoundBox auf Dauer im Takt. Die Option REALTIME, die Circle für USB-Ton empfiehlt, sperrt Geräte mit Full Speed wie die SoundBox nur auf dem Pi 1 bis 31.
Den ersten zurückgemeldeten Wert übernimmt Circle ungeprüft. Es verlangt nur ein Paket von mindestens drei Bytes und rechnet daraus die Grösse der folgenden Pakete1. Die SoundBox meldete am Anfang jedes Streams 0, weil ihre USB-Bibliothek TinyUSB das erste Paket abschickt, bevor die Firmware einen Wert eingetragen hat14. Circle baute daraus leere Pakete und hielt an einer Assertion an gemessen.
Beide Seiten sind korrigiert. Die Firmware der SoundBox meldet ab dem ersten Paket den Nennwert von 48 Frames je Millisekunde14. Circle übernimmt im Fork nur Werte zwischen 7/8 und 3/2 des Nennwerts und bleibt sonst beim Nennwert. Diese Prüfung liegt als Patch im Anhang C und wird Circle angeboten.
Was die SoundBox nach dem Einschalten spielt, legt das Profil fest, das zuletzt auf ihr gespeichert wurde. Ein stumm gespeichertes Profil hält sie stumm, an welchem Rechner sie auch hängt gemessen. Gespeichert wird ein Profil mit der Workbench von NeXTsound über „Save to SoundBox“14.
Mit einem Profil ohne Stummschaltung spielt die SoundBox am Pi 5 an Circle mit dieser Prüfung, und zwar mit beiden Ständen ihrer Firmware gemessen. Die Tonhöhe schwankt hörbar wie bei einem Vibrato gemessen. Das ist der Testton selbst, denn das Beispiel bewegt seine 440 Hz mit Absicht zehnmal je Sekunde um 5 Hz auf und ab1.
Zwischen Previous und der SoundBox steht die Host-Schicht. Sie rechnet die 44,1 kHz auf 48 kHz um, weil Circle das nicht tut, und sie dreht die Byte-Reihenfolge um. Ausserdem setzt sie die Lautstärke beim Start über die Lautstärkeregelung der SoundBox, die Circle über seinen Sound Controller anspricht. Heute erledigt das WirePlumber mit dem Wert 0,6145.
Steckt beim Start keine SoundBox, geht der Ton über HDMI, was Circle auf dem Pi 5 seit November 2024 kann1. Der Pi 4 hat zusätzlich einen Kopfhörerausgang, der Pi 5 nicht9. Eine Aufnahme über ein Mikrofon bietet das Image nicht.
Die SoundBox lässt sich auch im Betrieb anstecken und abziehen. Circle sucht das Gerät bei jedem Start der Tonausgabe neu unter den gemeldeten USB-Geräten, und die Liste dieser Geräte aktualisiert die Hauptschleife auf Kern 0 laufend. Zieht man die SoundBox ab, kehrt die Tonausgabe in ihren Ausgangszustand zurück und lässt sich später wieder starten1. Die Host-Schicht gibt den Ton also an die SoundBox, sobald sie da ist, und solange sie fehlt, über HDMI oder den Kopfhörerausgang. Ob die SoundBox auch am Pi 4 spielt, prüft Schritt 1 mit dem Beispiel von Circle.
8.4 Karte und USB-Stick
Eine SD-Karte oder ein USB-Stick bekommt vier FAT32-Partitionen, deren Aufteilung Abschnitt 8.12 beschreibt, und dasselbe Medium startet auf beiden Modellen. Auf jeder der beiden Systempartitionen liegen config.txt, die Images kernel8-rpi4.img und kernel_2712.img, die Device Trees beider Modelle mit dem Overlay des Pi 5 und für den Pi 4 die Firmware start4.elf mit fixup4.dat671. In der Datenpartition liegen die ROMs, das Plattenabbild von NeXTSTEP, previous.cfg und der Ordner, den NFS für NeXTSTEP freigibt. Previous liest und schreibt das Plattenabbild blockweise über die C-Bibliothek, und die Fassung von newlib für Circle, circle-newlib, reicht diese Aufrufe an FatFs weiter11. Für jedes Abbild gilt die Grenze von 2 GiB aus Abschnitt 4. NeXTSTEP 3.3 passt darunter.
Die Pfade in previous.cfg zeigen heute auf das Dateisystem von Linux. Ohne Linux legt die Host-Schicht feste Orte auf der Karte fest, und previous.cfg nennt die Dateien dort.
8.5 Speicher
Previous baut bei jedem Kaltstart jede NeXTdimension neu auf und gibt dabei ihre 68 MB frei, um sie gleich wieder anzufordern2. Mit den Blockgrössen, die Circle ab Werk hat, wäre dieser Speicher danach verloren1. Der Build richtet die Blockgrössen deshalb so ein, dass Circle diese Blöcke wiederverwendet.
Previous fordert diese Blöcke mit einer Ausrichtung auf 64 KiB an. Circle hält eine solche Ausrichtung nicht ein: circle-newlib reicht die Anforderung an Circle weiter, und Circle richtet einen Block höchstens auf die Länge einer Cache-Zeile aus111. Previous braucht die Ausrichtung aber nicht. Gibt es keine Funktion für ausgerichteten Speicher, nimmt es selbst ein einfaches malloc, und so baut der Fork es2.
8.6 Uhrzeit
Beim Start stellt Previous die Uhr des NeXT nach der Uhrzeit des Systems2. Auf dem Pi 5 kommt sie aus seiner Echtzeituhr, die Circle seit Juli 2024 auslesen kann1. Damit diese Uhr die Zeit über das Ausschalten behält, braucht der Pi 5 eine Batterie am Anschluss J515. Eine Echtzeituhr beschreibt die Dokumentation nur für den Pi 515. Auf dem Pi 4 holt Circle die Zeit deshalb per NTP1, sobald das Netz ab Schritt 5 steht. Bis dahin, und wenn kein Netz da ist, übernimmt die Host-Schicht die Zeit, die sie beim letzten Ausschalten auf die Karte geschrieben hat.
8.7 Ausschalten
Fährt NeXTSTEP herunter, beendet sich Previous2. Unter Linux startet die Konsole es danach neu5. Ohne Linux schliesst die Host-Schicht alle Dateien auf der Karte, schreibt die Uhrzeit dorthin und beendet das Image so, dass Circle den Pi ausschaltet1. Der Taster des Pi 5 schaltet ihn wieder ein9.
8.8 Netz
Previously bindet NeXTSTEP heute über SLiRP an. SLiRP bildet ein Netz nach und baut jede Verbindung über die Socket-Schnittstelle des Systems auf2. Die Socket-Schnittstelle von circle-stdlib ist experimentell, und ihre Dokumentation nennt kein select, das SLiRP braucht8. Schritt 5 setzt deshalb eine Brücke an die Stelle von SLiRP. Die Ethernet-Frames, die die Netzwerkkarte des NeXT sendet, gehen unverändert an den Ethernet-Anschluss des Pi, und was dort für den NeXT ankommt, geht an den NeXT.
Die Ethernet-Treiber von Circle nehmen nur Frames an die Adresse des Pi selbst an, an Broadcasts und an Multicast-Gruppen. Beim Pi 5 schaltet der Treiber dafür den Promiscuous Mode ab1. Beim Pi 4 trägt er diese Adressen in eine Filtertabelle des Chips ein1. Beide Treiber bekommen deshalb eine zweite Adresse für den NeXT, und die Netzschicht von Circle reicht Frames an diese Adresse an die Brücke weiter. Der NeXT erscheint damit wie ein echter NeXT mit eigener Adresse im lokalen Netz. In den Schritten 2 bis 4 hat er eine Netzwerkkarte ohne Kabel.
Die Server, die Previous für NeXTSTEP mitbringt, ziehen in Schritt 6 mit um. NFS, NetInfo, der Portmapper, Mount und Bootparam sind in Previous eigenständige Server mit rund 6.400 Zeilen. Mit SLiRP sind sie nur über drei kleine Hüllen um die Sockets verbunden, die heute an Loopback auf einen zufälligen Port binden. SLiRP leitet den Verkehr des NeXT an die Adresse 10.0.2.254 dorthin weiter2. In Schritt 6 bekommen die drei Hüllen eine Fassung für die Sockets von Circle. Diese können TCP und UDP und senden und empfangen auf Wunsch auch Broadcasts, über die NeXTSTEP seinen NetInfo-Server sucht1. Die Server laufen dann auf dem TCP/IP-Stack von Circle unter der Adresse des Pi im lokalen Netz. Der Pi übernimmt damit die Rolle, die bei NeXT ein Server im Netz hatte.
NeXTSTEP bleibt dadurch so eingestellt wie unter Previous heute, mit „Autoconfigure“ für Name und Adresse, „Dynamic“ für den Router und der Bindung an einen NetInfo-Server im Netz. So kommt es ohne weitere Einrichtung ins Netz2. Zwei Dienste, die heute SLiRP selbst erbringt, übernimmt dafür der Pi. Er beantwortet die BOOTP-Anfrage des NeXT mit einer Adresse, die Previously festlegt, und er meldet per RIP den Router des lokalen Netzes, woraus NeXTSTEP seinen Router lernt. Previously muss deshalb nichts in das Plattenabbild schreiben. Die Einrichtung ist eine Einstellung des Pi: welche Adresse der NeXT bekommt.
Der Ordner, den NFS freigibt, liegt auf der SD-Karte und erscheint in NeXTSTEP wie heute unter /Net. Unix-Rechte merkt sich Previous in erweiterten Dateiattributen, und die hat FAT nicht2. Für den Austausch von Dateien reicht das.
8.9 Einstellungen und Meldungen
Previous öffnet ab Werk beim Start seinen Einstellungsdialog und zeigt Fehler als Dialog an2. Bis Schritt 4 gibt es keinen Dialog. previous.cfg liegt dann fertig auf der Karte, der Dialog beim Start ist darin ausgeschaltet, und Fehlermeldungen gehen ins Protokoll. Das Protokoll schreibt die Host-Schicht in eine Datei auf der Karte, damit es das Bild des NeXT nicht überdeckt. Schritt 4 holt den Dialog dazu, den F12 öffnet. Er zeichnet heute auf Flächen von SDL3, und image/ gibt ihm eine kleine Zeichenschicht über dem Framebuffer.
8.10 Previously im Image
Previously bleibt eine Weboberfläche. Der Benutzer öffnet sie wie heute im Browser eines Geräts im selben Netz, unter dem Namen des Pi mit der Endung .local. Diesen Namen macht der mDNS-Dienst von Circle im Netz bekannt1.
Der Webserver von Circle genügt dafür nicht. Er nimmt den Inhalt einer Anfrage nur als Formular bis 2048 Byte an, schickt jede Antwort in einem Stück und schliesst danach die Verbindung. Server-Sent Events und WebSockets kennt er nicht1. Die Oberfläche von Previously schickt aber JSON, hört auf einen Strom von Ereignissen und fragt den Fortschritt laufender Arbeiten regelmässig ab5. circle-stdlib enthält dafür den Server Mongoose, und dessen Beispiel liefert Dateien von der Karte, eine Route mit JSON und einen WebSocket aus8. Previously im Image baut auf Mongoose auf.
Die Oberfläche bleibt eine einzige Codebasis für Linux und für das Image. Hinter ihr steht im Image statt des Dienstes in Python ein Teil von Previously in C++, der im selben Programm läuft wie der Emulator. Er bedient dieselben Routen für alles, was es im Image gibt, und sagt der Oberfläche, welche Fenster sie zeigt.
Einstellungen ändert Previously auf demselben Weg wie F12. Previous vergleicht an einer einzigen Stelle die Einstellungen vor und nach einer Änderung und entscheidet dort, was sofort wirkt und was einen Kaltstart braucht2. Einen Kaltstart brauchen die Maschine, der Speicher, das ROM, die Startoptionen, die Platten, die NeXTdimension und die MAC-Adresse. Sofort wirken unter anderem die Maus, der Ton, der Bildschirmmodus und der Anschluss ans Netz, und Disketten, magneto-optische Platten und CDs wechseln sofort. Previously ruft genau diese Stelle auf, und so entscheiden F12 und Previously immer gleich.
Die Anmeldung bleibt, wie sie ist: ein Passwort je Maschine, das der erste Besucher wählt5. Im Image liegt sein Hash in der Datenpartition. Über F12 hinaus bietet Previously gespeicherte Konfigurationen von Maschinen, Bildschirmfotos, Sicherungskopien der Platten auf dem Medium sowie Neustart und Ausschalten aus dem Browser.
8.11 Einrichtung
Eine Karte oder ein USB-Stick wird nicht am Pi eingerichtet, sondern am Mac. Eine Mac-App stellt das Medium nach Wunsch des Kunden zusammen. Sie ist ein Werkzeug für den, der die Medien ausliefert, und der Benutzer bekommt sie nicht zu sehen.
Die App teilt das Medium in die Partitionen aus Abschnitt 8.12 auf und kopiert das Release des Images hinein. Dann holt sie das gewählte System, so wie Previously es heute tut. Es ist eines von sechs vorbereiteten Systemen von NeXTSTEP 2.2 bis OPENSTEP 4.2, ein Archiv von archive.org, das zu einem Abbild von 2.012.774.400 Byte entpackt wird und auch die ROMs mitbringt5. Zuletzt schreibt sie previous.cfg, den Namen des Pi im Netz und das Zertifikat, mit dem Updates den Server prüfen. Die Liste der Systeme steht heute als Tabelle im Code des Dienstes. Sie wird eine Datei, die der Dienst, die App und das Image gemeinsam lesen.
Ein USB-Stick funktioniert wie eine Karte. Pi 4 und Pi 5 starten von USB, wenn die Startreihenfolge im EEPROM es vorsieht. Ist dort keine Reihenfolge eingetragen, versucht der Pi zuerst die Karte und dann USB4. Hängt ein Pi 5 an einem Netzteil für 3 A, startet er von USB nur mit usb_max_current_enable=1 in der config.txt4. Circle spricht einen USB-Stick als Laufwerk USB: an1, und das Image sucht seine Daten auf dem Medium, von dem es gestartet ist.
Auf dem Medium gilt FAT32, denn exFAT ist in der Bibliothek für FAT abgeschaltet. Eine einzelne Datei darf deshalb höchstens 4 GiB minus ein Byte gross sein1.
8.12 Updates
Previous und Previously sind im Image ein einziges Programm. Ein Update tauscht deshalb beide zusammen aus und kommt als Release von Previously mit einer Versionsnummer. Wie heute fragt Previously die Releases auf GitHub ab5.
Dafür braucht das Image HTTPS. circle-stdlib bringt Mbed TLS mit und einen Client, der eine Datei über HTTPS holt8. Dieser Client folgt keiner Umleitung und legt den Inhalt im Speicher ab. GitHub leitet den Download einer Datei aus einem Release auf einen anderen Server um, und Previously folgt dieser Umleitung deshalb selbst. Ein Image ist klein genug für den Speicher. Den Server prüft der Client nur, wenn ein Zertifikat auf dem Medium liegt8, und dieses Zertifikat legt die Mac-App dazu. Jede geladene Datei prüft Previously gegen ihre Prüfsumme SHA-256 aus dem Release, wie es der Dienst unter Linux heute tut5.
Damit ein misslungenes Update den Pi nicht unbrauchbar macht, hat das Medium vier Partitionen. Die erste enthält nur autoboot.txt, und darin steht, von welcher Partition der Pi startet6. Die zweite und die dritte enthalten je einen vollständigen Stand des Images mit seiner config.txt. Die vierte enthält die Daten: previous.cfg, die Abbilder der Platten, den Ordner für NFS und den Hash des Passworts. Ein Update schreibt in die Systempartition, von der der Pi gerade nicht gestartet ist, und startet einmal von ihr. Circle kann den Pi dafür mit der Nummer einer Partition neu starten, auf demselben Weg wie reboot mit einer Partitionsnummer unter Linux1. Startet der neue Stand sauber, schreibt er autoboot.txt um und gilt von da an. Die Datenpartition fasst ein Update nie an.
Startet der neue Stand nicht, führt das nächste Aus- und Einschalten auf den alten Stand zurück, weil autoboot.txt noch auf ihn zeigt und die Nummer für den einen Neustart nur in einem Register des Chips steht abgeleitet. Am Gerät geprüft ist das nicht.
9. Vorbilder
Mehrere Projekte bringen Emulatoren bereits ohne Linux auf den Pi. Drei davon bauen auf Circle auf und zeigen, was für Previous wichtig ist. Previous selbst ist aus Hatari entstanden, dem Emulator für den Atari ST2.
| Projekt | Emulator | Pi 4 und Pi 5 | Was es zeigt |
|---|---|---|---|
| BMAtariST | Hatari | beide | Hatari hat einen Prozessorkern aus derselben Quelle wie Previous, aus WinUAE. Er läuft unverändert auf Circle und auf Kern 1. Die eigene Schicht in src/port umfasst rund 4.800 Zeilen12. |
| BMA800XL | atari800 | beide, den Pi 5 seit Version 1.3.0 vom 14.10.2026 | Eigene Bildschirmtreiber für den Pi 4 und den Pi 5, den für den Pi 5 auf einem Pi 500 getestet, und Ton über HDMI9. |
| BMC64 | VICE | keiner | Gepflegt, der letzte Commit ist vom 20.10.2026. Der Emulator läuft auf Kern 1, die Interrupts bleiben auf Kern 016. |
BMAtariST kommt Previous am nächsten. Es ist Version 0.1.0 und noch nicht veröffentlicht. Für den Pi 5 sagt es, dass es dort läuft, nicht aber, auf welcher Hardware es getestet wurde12. Keines der Projekte zeigt, wie schnell ein 68040 mit dem Takt eines NeXT oder ein i860 ohne Linux auf dem Pi läuft.
10. Der Plan in sechs Schritten
Jeder Schritt wird ein eigenes Issue und liefert für sich ein Ergebnis, das auf dem Pi 4 und dem Pi 5 läuft.
| Schritt | Arbeit | Ergebnis |
|---|---|---|
| 1. Fork und Build | Der Fork mit dem Spiegel von Previous, das Makefile auf den Build-Regeln von Circle für beide Modelle und eine Host-Schicht, die zunächst nur Platzhalter enthält. Das Protokoll geht in eine Datei auf der Karte. Circle bekommt die Prüfung des Takts aus Abschnitt 8.3, und das Beispiel von Circle für USB-Ton spielt mit der SoundBox mini auf beiden Modellen einen Ton mit fester Tonhöhe. Dazu wird die Last des Emulators auf dem heutigen Pi gemessen, als Vergleich für später. | Eine Karte, die auf dem Pi 4 und dem Pi 5 startet und das Protokoll von Previous auf die Karte schreibt. Dazu die SoundBox mit einem Ton fester Tonhöhe an Circle auf beiden Modellen. |
| 2. NeXTSTEP startet | Threads auf festen Kernen, das Bild über den Framebuffer der Firmware, Tastatur und Maus, Ton an die SoundBox mit Umrechnung auf 48 kHz, sonst über HDMI, Dateien und Pfade auf der Karte, der Speicher, die Uhrzeit und das Ausschalten. | Eine Karte, auf der ein NeXTcube ohne Linux auf beiden Modellen bis zum Arbeitsplatz von NeXTSTEP startet und sich beim Herunterfahren ausschaltet, dazu der Vergleich mit Linux. |
| 3. Bildschirm und NeXTdimension | Der Bildschirmtreiber aus BMA800XL für beide Modelle, die Bildausgabe der NeXTdimension und ihr i860 auf Kern 2. | Ein NeXTcube mit NeXTdimension in Farbe, in der gewählten Auflösung und ohne Reissen. |
| 4. Einstellungen | Die Zeichenschicht für die Dialoge von Previous. | Alles, was in previous.cfg steht, lässt sich am Gerät mit F12 ändern, und Fehler erscheinen als Dialog. |
| 5. Netzbrücke | Die Brücke in der Ethernet-Emulation von Previous, die zweite Adresse in den Ethernet-Treibern beider Modelle und die Uhrzeit per NTP für den Pi 4. | Die Frames des NeXT gehen ins lokale Netz. Mit einer von Hand eingetragenen Adresse ist NeXTSTEP dort erreichbar. |
| 6. NFS und NetInfo | Die Hüllen um die Sockets für die Server von Previous, die Antwort auf BOOTP mit der Adresse aus Previously und die RIP-Meldung für den Router. | NeXTSTEP kommt wie heute ohne Einrichtung ins Netz und findet den Ordner auf der Karte unter /Net. |
Neben den Schritten laufen drei Vorhaben. Die Einrichtung über die Mac-App beginnt mit der Aufteilung des Mediums aus Abschnitt 8.12 und braucht Schritt 2. Previously im Image braucht Schritt 2 und das Netz des Pi, aber nicht die Netzbrücke. Updates brauchen die Einrichtung und Previously im Image. Nach Schritt 2 folgen ausserdem Plattenabbilder ab 2 GiB, für die circle-newlib Dateipositionen mit 64 Bit rechnen muss.
11. Was daraus nicht folgt
Nicht, dass NeXTSTEP ohne Linux schneller läuft. Der Emulator rechnet mit demselben Code. Was wegfällt, sind andere Prozesse und ein Compositor. Ob das am Bildschirm einen Unterschied macht, zeigt erst der Vergleich in Schritt 2.
Nicht, dass der Pi 4 einen NeXT so schnell emuliert wie der Pi 5. Seine Kerne sind älter. Ob er einen NeXTcube, und ob er ihn mit NeXTdimension, in voller Geschwindigkeit emuliert, zeigen erst die Schritte 2 und 3.
Nicht, dass ein 68040 mit NeXTdimension ohne Betriebssystem das Tempo hält, das er unter Linux hat. Kein Vorbild zeigt das. Messbar ist es erst nach Schritt 3.
Nicht, dass die SoundBox an Circle auf dem Pi 4 spielt. Geprüft ist der Pi 5. Den Pi 4 prüft Schritt 1.
Nicht, dass die neue Firmware der SoundBox allein genügt. Geprüft wurde nur mit einem Circle, das den Takt schon prüft, und daran spielt die SoundBox mit beiden Ständen ihrer Firmware. Ob ein Circle ohne diese Prüfung mit der neuen Firmware spielt, zeigt erst ein Versuch mit einem solchen Circle.
Nicht, dass die SoundBox an Circle eine feste Tonhöhe sauber hält. Gehört wurde nur der Testton, und der schwankt mit Absicht. Kleine Fehler im Takt gehen darin unter. Einen Ton mit fester Tonhöhe prüft Schritt 1.
Nicht, dass der Bildschirmtreiber mit jedem Bildschirm läuft. BMA800XL hat ihn für den Pi 5 seit dem 14.10.2026 und auf einem Pi 500 getestet.
Nicht, dass der freigegebene Ordner Unix-Rechte kennt. Er liegt auf FAT, und Previous merkt sich diese Rechte in erweiterten Dateiattributen, die FAT nicht hat.
Nicht, dass eine heutige previous.cfg unverändert weiterläuft. Ihre Pfade zeigen auf das Dateisystem von Linux.
Nicht, dass der Pi jederzeit ausgeschaltet werden darf. Wie heute ist das Plattenabbild nur sicher, wenn NeXTSTEP vorher heruntergefahren ist5.
Nicht, dass die Uhr nach einem Stromausfall stimmt. Der Pi 5 braucht dafür eine Batterie an seiner Echtzeituhr15, der Pi 4 das Netz.
Nicht, dass ein hängendes Update von selbst zurückfällt. Der alte Stand kommt erst mit dem nächsten Aus- und Einschalten zurück, und auch das ist abgeleitet und am Gerät nicht geprüft.
Nicht, dass Previously im Image so robust läuft wie unter Linux. Mongoose läuft auf der Socket-Schnittstelle von circle-stdlib, und deren Dokumentation nennt sie experimentell8.
Nicht, dass Circle unverändert genügt. Die Netzbrücke und grosse Plattenabbilder brauchen Änderungen an Circle und an circle-newlib, und der Fork baut Circle mit der Prüfung des Takts aus Abschnitt 8.3.
Nicht, dass das Image auf einem anderen Board läuft. Es wird für den Pi 4 und den Pi 5 gebaut. Für jedes andere Board bleibt Previously, wie es heute ist.
Nicht, dass unter dem Emulator nichts mehr liegt. Die Firmware bleibt, und das Image hängt von ihr ab, etwa für den Framebuffer.
12. Schluss
Der Weg ohne Linux ist machbar, aber er lohnt sich kaum. Seine Vorteile sind klein, und keiner davon ist gemessen. Der Aufwand dagegen ist gross: sechs Schritte, drei weitere Vorhaben und ein zweites Previously in C++.
Ohne Linux gewinnt der Pi vor allem den Charakter eines Geräts. Unter dem Emulator läge nichts mehr, das gepflegt werden muss: keine Pakete, keine neuen Fassungen des Betriebssystems, keine wechselnden Versionen von Python und kein SSH. Der Start würde kürzer, weil Linux nicht mehr startet, doch um wie viel, ist nicht gemessen. NeXTSTEP selbst braucht danach bis zu einer halben Minute bis zur Anmeldung5. Ob Ton und Bild gleichmässiger laufen, wenn jeder Thread einen Kern für sich hat, bleibt offen, solange unter Linux kein Ruckeln gemessen ist.
Schneller rechnet der Emulator ohne Linux nicht, denn er führt denselben Code aus. Sicherer gegen einen Stromausfall wird er auch nicht, denn das Plattenabbild ist ohne Linux genauso nur dann sicher, wenn NeXTSTEP vorher heruntergefahren ist.
Dafür kämen neue Abhängigkeiten und Einschränkungen. Das Image hinge an Circle und an circle-stdlib, deren Sockets als experimentell gelten8. Für Updates, für FAT mit mehreren Partitionen und für HTTPS ohne Umleitungen bräuchte es eigenen Code. Previously entstünde in C++ ein zweites Mal neben dem Dienst in Python, und zwei Fassungen derselben Schnittstelle laufen mit der Zeit auseinander. Das Medium hätte FAT32 ohne Unix-Rechte und Abbilder bis 2 GiB, bis circle-newlib mit 64 Bit rechnet. Für die Fehlersuche gäbe es weder ein Terminal noch SSH.
Den Charakter eines Geräts bekommt Previously auch mit Linux, wenn Linux auf das Nötigste zugeschnitten wird. SDL3 zeichnet ohne Compositor direkt über KMS und DRM17, und damit entfällt cage. Raspberry Pi OS kann sein Root-Dateisystem mit einem Overlay im Arbeitsspeicher schreibgeschützt halten und die Startpartition gegen Schreiben sperren18. Die Abbilder und die Konfiguration liegen dann auf einer eigenen beschreibbaren Partition. Der Start wird kürzer, wenn auf dem Pi nur noch läuft, was der Emulator braucht.
Dieses Paper bleibt deshalb eine Recherche. Umgesetzt wird der zugeschnittene Aufbau mit Linux. Vorher werden Startzeit und Last unter dem heutigen Linux gemessen, damit sich jeder Schritt an diesem Ausgangswert prüfen lässt. Der Weg ohne Linux kommt erst wieder in Frage, wenn die Messung ein Problem zeigt, das nur er löst.
Quellennachweis
Achtzehn Quellen, in der Reihenfolge ihres Auftretens.
- Stange, R.: Circle, a C++ bare metal programming environment for the Raspberry Pi. Commit 7a81e1b vom 25.09.2026 auf master, darin
README.md,CHANGELOG.md,boot/README,boot/config64.txt,doc/cmdline.txt,doc/realtime.txt,sample/README,include/circle/sysconfig.h,include/circle/netdevice.h,include/circle/net/socket.h,include/circle/usb/usbkeyboard.h,lib/macb.cpp,lib/bcm54213.cpp,lib/interruptgic.cpp,lib/usb/usbdevice.cpp,lib/usb/usbaudiostreaming.cpp,lib/sound/usbsoundbasedevice.cpp,lib/alloc.cpp,include/circle/heapallocator.h,sample/29-miniorgan/kernel.cpp,sample/34-sounddevices/kernel.cpp,sample/34-sounddevices/oscillator.cpp,include/circle/net/http.h,include/circle/net/httpdaemon.h,lib/net/httpdaemon.cpp,lib/net/mdnsdaemon.cpp,lib/bcmwatchdog.cpp,lib/usb/usbmassdevice.cpp,addon/fatfs/ffconf.hundaddon/fatfs/diskio.cpp. Fundstellen gelesen Quelle↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ - Grabher, A. und andere: Previous, a NeXT Computer emulator. Subversion, Trunk in Revision 1858 vom 10.10.2026, mit den Anleitungen
networking.howto.txtundfilesharing.howto.txtsowiesrc/change.cundsrc/dialog.c. Fundstellen gelesen Quelle↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ - Raspberry Pi Ltd: rpi-eeprom,
README.md. Fundstelle gelesen Quelle↩ - Raspberry Pi Ltd: Raspberry Pi hardware, EEPROM boot flow. Abschnitte zum ersten und zweiten Bootloader, „Differences on Raspberry Pi 5“ und zu
tryboot, dazu die Abschnitte „Raspberry Pi bootloader configuration“ und „USB mass storage boot“, im Quelltext der Dokumentation in Commit ddea98e. Abschnitte gelesen Quelle↩↩↩↩ - Previously: Running it (
docs/running-it.md),admin/previously/setup.py,admin/previously/machines.py,admin/previously/systems.py,admin/previously/server.py,admin/previously/release.py,admin/previously/password.pyundadmin/interface/app/service.js, Stand f846a68. Fundstellen gelesen Quelle↩↩↩↩↩↩↩↩↩↩↩↩↩ - Raspberry Pi Ltd: config.txt, Boot options. Abschnitte „kernel“ und „pciex4_reset“, die bedingten Abschnitte für einzelne Modelle und der Abschnitt zu
autoboot.txt. Abschnitte gelesen Quelle↩↩↩↩ - Stange, R.: Circle documentation, Appendix Raspberry Pi 5. Abschnitte zur Installation und „Display support“, der Absatz zum RP1 und der zum Prozessor. Abschnitte gelesen Quelle↩↩↩↩↩
- Mühlstrasser, S.: circle-stdlib, C and C++ standard library support for Circle. Commit 4fbab62 vom 25.09.2026, darin
README.md,doc/SOCKETS.md,configure,libs/libcxx-threading/src/thread.cpp,libs/mongoose/mongoose.h,samples/06-socket,circle-mbedtls.md,src/circle-mbedtls/httpclient.cpp,src/circle-mbedtls/tlssimpleclientsocket.cppundsamples/mbedtls/06-webclient. Fundstellen gelesen Quelle↩↩↩↩↩↩↩↩↩↩ - BMA800XL: Raspberry Pi 5, Pi 500 and Pi 500+ (
docs/PI5.md), Commit 43cac1c vom 20.10.2026, und Commit d81a031 „Pi 5: fixes from testing on a Pi 500“. Volltext gelesen Quelle↩↩↩↩↩↩ - Stange, R.: Multi-core support (
doc/multicore.txtin Circle). Commit 7a81e1b. Volltext gelesen Quelle↩↩↩↩ - Mühlstrasser, S.: circle-newlib,
libgloss/circle/io.cppundlibgloss/circle/mem.c. Commit 5b9ff4c vom 08.08.2026. Fundstellen gelesen Quelle↩↩↩ - BMAtariST: A bare metal Atari ST, STE, TT and Falcon emulator for the Raspberry Pi. Commit 710b5f7 vom 20.10.2026, darin
README.md,CHANGELOG.md,docs/PI5.mdunddocs/THIRD_PARTY.md. Fundstellen gelesen Quelle↩↩↩ - SDL: SDL_scancode.h. SDL3, Zweig main am 21.10.2026. Fundstelle gelesen Quelle↩
- NeXTsound: Firmware und Workbench der NeXT SoundBox mini. Commit 35b03e2 vom 21.10.2026, darin
Firmware/USB/descriptors.c,Firmware/USB/control.c,Firmware/Core/audio.c,Firmware/Core/device.c,Firmware/ThirdParty/TinyUSB-0.21.0-feedback.patch,Shared/Sources/NeXTsoundProtocol/include/nxs_protocol.hundDocumentation/App.md, mit den Pull Requests #63 und #64. Fundstellen gelesen Quelle↩↩↩↩ - Raspberry Pi Ltd: Raspberry Pi hardware, Real Time Clock (RTC). Volltext gelesen Quelle↩↩↩
- Rossi, R.: BMC64, a bare metal C64 emulator for the Raspberry Pi. Commit 34e08e9 vom 20.10.2026, darin
README.md,docs/SCOPE.mdundsrc/viceapp.cpp. Fundstellen gelesen Quelle↩ - SDL: KMS/DRM video driver,
src/video/kmsdrm/. SDL3, Zweig main am 21.10.2026. Verzeichnis eingesehen Quelle↩ - Raspberry Pi Ltd: Configuration, Performance, Enable or disable overlay file system. Quelltext
computers/configuration/performance.adoc, Zweig master am 21.10.2026. Abschnitt gelesen Quelle↩
Anhang
Die gelesenen Stände, die Fundstellen jeder Aussage und das Rohmaterial. Für die Aussagen oben braucht man das hier nicht.
A. Gelesene Stände
Alle Quellen wurden am 21.10.2026 gelesen. Jede Aussage oben stützt sich auf den Quellcode und die Dokumentation in diesen Ständen. Ausgenommen sind die Aussagen, die als gemessen markiert sind. Sie stammen aus der Prüfung am Pi 5, die Abschnitt 1 beschreibt. Die Karte dafür trug Circle in Commit 7a81e1b mit dem Patch aus Anhang C und zusätzlichen Zählern auf dem Bildschirm. Die Kommandozeile war sounddev=sndusb soundopt=24.
| Gegenstand | Stand | Datum des Stands |
|---|---|---|
| Previous, Subversion-Trunk | Revision 1858 | 10.10.2026 |
| Circle, Zweig master | 7a81e1b | 25.09.2026 |
| circle-stdlib | 4fbab62 | 25.09.2026 |
| circle-newlib | 5b9ff4c | 08.08.2026 |
| BMA800XL | 43cac1c | 20.10.2026 |
| BMAtariST | 710b5f7 | 20.10.2026 |
| BMC64 | 34e08e9 | 20.10.2026 |
| NeXTsound, Firmware und Workbench der SoundBox mini | 35b03e2 | 21.10.2026 |
| SDL3, Zweig main | nicht erfasst | 21.10.2026 gelesen |
| Raspberry Pi documentation und rpi-eeprom | nicht erfasst, die Abschnitte zu USB, tryboot und autoboot.txt im Quelltext in ddea98e | 21.10.2026 gelesen |
| Circle documentation auf readthedocs | latest | 21.10.2026 gelesen |
| Previously | f846a68 | 21.10.2026 |
B. Fundstellen
Pfade in Previous beziehen sich auf den Trunk in Revision 1858, Pfade in Circle auf Commit 7a81e1b.
| Aussage | Fundstelle |
|---|---|
| Sechs Header nennen die Schnittstelle zum System | Previous src/includes/host.h:19,27, audio.h:11, screen.h:24, event.h:24, keymap.h:11, statusbar.h:29 |
host.h bezieht seine Typen aus SDL3 | Previous src/includes/host.h:13,20-25 |
127 SDL-Funktionen; alle übersetzten stehen in src/gui-sdl/ und src/dimension/nd_sdl.cpp | Zählung über alle .c und .cpp. Übrig sind src/slirp/nfs/VDNS.cpp:80, das src/slirp/CMakeLists.txt:30-33 nicht übersetzt, und src/dsp/dsp_cpu.c:777,933 unter DSP_COUNT_IPS mit dem Wert 0 |
src/gui-sdl/ mit 11.686 Zeilen, die Dialoge mit 6.491, Previous mit 164.245 | Zählung mit wc -l über .c und .h; Anhang C, previous-host-dependencies.md, Abschnitt 16 |
| Kein JIT | Previous src/cpu/sysconfig.h:49 |
Speicher für die emulierte Maschine über posix_memalign oder aligned_alloc, ausgerichtet auf 64 KiB, sonst über malloc; Zugriff Byte für Byte auf ARM | Previous src/cpu/maccess.h:21-28,126-139 |
| Circle richtet höchstens auf eine Cache-Zeile aus, circle-newlib reicht die Anforderung weiter | Circle lib/alloc.cpp:31-35, include/circle/heapallocator.h:38; circle-newlib libgloss/circle/mem.c:41-46 |
| Tonausgabe über USB sucht das Gerät bei jedem Start, kehrt nach dem Abziehen in den Ausgangszustand zurück | Circle lib/sound/usbsoundbasedevice.cpp:124-218,299-328,534-575, sample/29-miniorgan/kernel.cpp:106 |
| Die Threads und ihre Reihenfolge beim Start | Previous src/main.c:298,349-351, src/dimension/i860.cpp:543-559, src/dimension/dimension.cpp:39-75, src/NextBus.cpp:167-184 |
| Bis zu drei NeXTdimension, ohne eigenen Kern alle i860 auf dem Thread des Prozessors | Previous src/includes/configuration.h:380, src/configuration.c:549, src/dimension/i860.cpp:544-549 |
| Previously richtet höchstens eine NeXTdimension ein | Previously admin/previously/machines.py:137-138 |
| 1120 mal 832 Bildpunkte bei 68 Hz | Previous src/gui-sdl/sdlscreen.c:26-27, src/video.c:25 |
| Stereo mit 16 Bit bei 44,1 kHz, höherwertiges Byte zuerst | Previous src/snd.c:25,327, src/gui-sdl/sdlaudio.c:156 |
| Die Uhr des NeXT folgt beim Start der Uhrzeit des Systems | Previous src/timing.c:277 |
| Previous beendet sich, wenn NeXTSTEP herunterfährt | Previous src/rtcnvram.c:340-343,630-633 |
| SLiRP ist die Vorgabe und braucht die Socket-Schnittstelle an über hundert Stellen | Previous src/configuration.c:455; Anhang C, previous-host-dependencies.md, Abschnitte 9 und 17 |
| NFS, NetInfo, Portmapper, Mount und Bootparam als eigene Server mit 6.439 Zeilen | Previous src/slirp/rpc/, Zählung mit wc -l |
| Die Hüllen um die Sockets binden an Loopback auf einen zufälligen Port | Previous src/slirp/rpc/udpsocket.c:55,70-71, src/slirp/rpc/tcpsocket.c:64,70-71,84,127 |
| SLiRP leitet den Verkehr an 10.0.2.254 an die Server | Previous src/slirp/ctl.h:14,21, src/slirp/socket.c:505-511, networking.howto.txt:32-34 |
| SLiRP beantwortet BOOTP und meldet den Router per RIP | Previous src/slirp/bootp.c:190-192,291, src/slirp/slirp.c:688-690 |
| Mit SLiRP richtet sich das Netz von NeXTSTEP 3.3 selbst ein; ohne SLiRP braucht es Werte aus dem lokalen Netz | Previous networking.howto.txt:1-14 |
Der freigegebene Ordner erscheint unter /Net | Previous filesharing.howto.txt:1-5 |
| Unix-Rechte in erweiterten Dateiattributen | Previous src/slirp/rpc/vfs.c:469-501 |
| Der Dialog öffnet ab Werk beim Start und zeigt auch Fehlermeldungen | Previous src/configuration.c:400, src/main.c:172,195,313-318 |
| Die Generatoren des 68k-Kerns laufen auf dem Build-Rechner | Previous src/cpu/CMakeLists.txt:15-39 |
| Previous stammt von Hatari ab | Previous readme.previous.txt:37-39 |
| Was Circle auf dem Pi 5 unterstützt | Circle README.md:91,100,101,116,121,124,131,137,144,148,150,160,162-164 |
| Pi 5 seit Step 46 (28.02.2024), Echtzeituhr und Ausschalten seit Step 47 (09.07.2024), HDMI-Ton seit Step 48 (08.11.2024) | Circle CHANGELOG.md, Abschnitte zu Step 46 bis 48, darin Zeilen 248 bis 250 |
Ein Image je Modell, config.txt wählt mit [pi4] und [pi5] | Circle Rules.mk:110-118, boot/config64.txt |
| Dateien des Pi 4 auf der Karte | Circle boot/README:22-39 |
| Interrupts auf Kern 0, Scheduler nur auf Kern 0, Schalter für mehrere Kerne, Cortex-A72 im Pi 4 | Circle doc/multicore.txt:3-7,17-19,62-64, include/circle/sysconfig.h:153-158, lib/interruptgic.cpp:165-176 |
| Grosse Blöcke gehen beim Freigeben verloren, Blockgrössen einstellbar | Circle include/circle/sysconfig.h:72-89 |
| Grösse des Images höchstens 2 MB, mit circle-stdlib 4 MB | Circle include/circle/sysconfig.h:33-38, circle-stdlib configure:20,69 |
| Lüfter des Pi 4 und des Pi 5 | Circle doc/cmdline.txt:72-77 |
| Keine Umrechnung der Abtastrate in den Klassen für Ton | Suche nach Resampling in Circle lib/sound/ und include/circle/sound/ ohne Treffer |
| USB-Ton: Klassen 1.0 und 2.0, Stereo, 16 und 24 Bit, Pi 4 ausdrücklich, Code für Pi 4 und 5 | Circle CHANGELOG.md:317,356, lib/sound/usbsoundbasedevice.cpp:235,253,493, sample/README:30,48 |
| Asynchroner Takt über den Feedback-Endpunkt | Circle lib/usb/usbaudiostreaming.cpp:345-362,1053-1086 |
| Circle prüft den zurückgemeldeten Wert nur auf Status und eine Länge ab drei Bytes und rechnet daraus die Paketgrösse | Circle lib/usb/usbaudiostreaming.cpp:1062-1086 |
| Die Prüfung des Takts im Fork: 7/8 bis 3/2 des Nennwerts, sonst der Nennwert | Anhang C, circle-usb-audio-feedback-check.patch |
| Der Testton des Beispiels: 440 Hz, von einem Oszillator mit 10 Hz um 5 Hz moduliert | Circle sample/34-sounddevices/kernel.cpp:172-178,199, sample/34-sounddevices/oscillator.cpp:110-118 |
REALTIME sperrt Full Speed nur auf dem Pi 1 bis 3 | Circle lib/usb/usbdevice.cpp:170-177, doc/realtime.txt:15-21 |
| Ethernet des Pi 5: Promiscuous Mode aus | Circle lib/macb.cpp:1186 |
| Ethernet des Pi 4: Filtertabelle mit Broadcast, eigener Adresse und Multicast | Circle lib/bcm54213.cpp:1074-1119 |
| Senden und Empfangen einzelner Frames | Circle include/circle/netdevice.h:68,74 |
| Sockets von Circle mit TCP, UDP und Broadcasts | Circle include/circle/net/socket.h:38,91-119 |
| Tasten als rohe Codes der USB-Norm, Umschalttasten als Bitmaske | Circle include/circle/usb/usbkeyboard.h:32,56-58 |
Ein std::thread nur mit libc++, als Aufgabe des kooperativen Schedulers | circle-stdlib README.md:31-50, libs/libcxx-threading/src/thread.cpp:90-215 |
Sockets von circle-stdlib experimentell, select nicht genannt | circle-stdlib doc/SOCKETS.md:5-10,34-73 |
| Dateipositionen mit 32 Bit und Vorzeichen | circle-newlib libgloss/circle/io.cpp:365-425,688 |
| Die C-Bibliothek reicht Dateizugriffe an FatFs weiter | circle-newlib libgloss/circle/io.cpp:238,296,332,400,430,902 |
| Die SoundBox mini: USB Audio Class 2.0, Stereo, 48 kHz, 16 oder 24 Bit, asynchron mit Feedback | NeXTsound Firmware/USB/descriptors.c:49,53,59,75-76, Firmware/Core/include/nxs_audio.h:10, Shared/Sources/NeXTsoundProtocol/include/nxs_protocol.h:31 |
| TinyUSB schickt das erste Paket eines Streams vor dem Eintrag der Firmware; die Firmware meldet ab dem ersten Paket den Nennwert | NeXTsound Firmware/ThirdParty/TinyUSB-0.21.0-feedback.patch, Firmware/USB/control.c:211-229, Firmware/Core/audio.c:176-178 |
| Die SoundBox startet mit dem zuletzt gespeicherten Profil | NeXTsound Firmware/Core/device.c:45-50 |
| Speichern über „Save to SoundBox“ | NeXTsound App/Workbench/Sources/NeXTsoundWorkbench/WorkbenchModel.swift:172, IOHIDBoardDiscovery.swift:136, Documentation/App.md |
| Grösse des Abbilds von NeXTSTEP 3.3 | Previously admin/previously/systems.py:37-39 |
| Die Scancodes von SDL sind die Codes der USB-Norm | SDL include/SDL3/SDL_scancode.h:47-59 |
| Firmware des Pi 5 im EEPROM, Bootloader nur als fertige Binärdatei | Raspberry Pi documentation, bootflow-eeprom.adoc, „Differences on Raspberry Pi 5“; rpi-eeprom README.md:2 |
Die Firmware lädt kernel_2712.img und setzt den RP1 zurück | Raspberry Pi documentation, config_txt/boot.adoc:177-183 und Abschnitt „kernel“ |
| Echtzeituhr des Pi 5, Batterie am Anschluss J5 | Raspberry Pi documentation, raspberry-pi/rtc.adoc:3,50 |
| Bildschirmtreiber, Auflösungen, eine Seite im Framebuffer, Ton über HDMI, kein Kopfhörerausgang am Pi 5, Taster | BMA800XL docs/PI5.md:3-43 |
| Hatari unverändert, auf Kern 1, läuft auf dem Pi 5 | BMAtariST README.md:116,138, docs/PI5.md:3 |
| BMC64 schliesst den Pi 4 und neuere aus, der Emulator läuft auf Kern 1 | BMC64 docs/SCOPE.md:21, src/viceapp.cpp:883-884 |
| Heute: Konsole mit Anmeldung, cage, Neustart nach dem Ende von Previous | Previously docs/running-it.md:13,71 |
| Heute: Schaden am Abbild, wenn Previous mitten im Betrieb endet | Previously docs/running-it.md:86,131 |
| Heute: Ton über PipeWire an einen Lautsprecher, Startlautstärke 0,614, Statuszeile aus | Previously admin/previously/setup.py:94-96,191,886,1408 |
| Heute: das Netz des NeXT folgt der gewählten Maschine | Previously admin/previously/machines.py:290-291 |
Der Webserver von Circle: GET, HEAD und POST, Formulare bis 2048 Byte, eine Antwort in einem Stück mit Connection: close, keine WebSockets und keine Server-Sent Events | Circle include/circle/net/http.h:31, lib/net/httpdaemon.cpp:254-285,341-350,486-503,549-573; Suche nach „websocket“ und „event-stream“ ohne Treffer |
mDNS-Dienst für <Name>.local | Circle lib/net/mdnsdaemon.cpp:29-31,169-215 |
| Mongoose in circle-stdlib, das Beispiel mit Dateien von der Karte, JSON und WebSocket, Sockets als experimentell bezeichnet | circle-stdlib libs/mongoose/mongoose.h:23, samples/06-socket/kernel.cpp:84-135,236, doc/SOCKETS.md |
| Die Oberfläche von Previously spricht JSON, hört auf Ereignisse und fragt den Fortschritt ab | Previously admin/interface/app/service.js:53-127, admin/previously/server.py:866-909 |
| Eine Stelle entscheidet zwischen sofortiger Wirkung und Kaltstart | Previous src/change.c:47-230,248-349, src/dialog.c:47-75 |
| Ein Passwort je Maschine, vom ersten Besucher gewählt | Previously admin/previously/password.py:31-45 |
| Sechs vorbereitete Systeme von archive.org als Tabelle im Code | Previously admin/previously/systems.py:28,73-98 |
Startreihenfolge ohne Eintrag: erst die Karte, dann USB; Pi 5 an 3 A braucht usb_max_current_enable=1 | Raspberry Pi documentation raspberry-pi/eeprom-bootloader.adoc:141-142, raspberry-pi/bootflow-eeprom.adoc:78 |
USB-Sticks als umsd und Laufwerk USB:, exFAT abgeschaltet | Circle lib/usb/usbmassdevice.cpp:407, addon/fatfs/ffconf.h:186,246, addon/fatfs/diskio.cpp:28-37 |
| Der HTTPS-Client folgt keiner Umleitung, liest in einen Puffer und prüft den Server nur mit einem Zertifikat auf dem Medium | circle-stdlib src/circle-mbedtls/httpclient.cpp:89,203-226,258-266, src/circle-mbedtls/tlssimpleclientsocket.cpp:91-115 |
| Releases auf GitHub und Prüfung mit SHA-256 | Previously admin/previously/release.py:41, admin/previously/setup.py:1057-1118 |
autoboot.txt wählt die Startpartition | Raspberry Pi documentation config_txt/autoboot.adoc:15-19,53-94 |
Neustart in eine bestimmte Partition über PM_RSTS | Circle lib/bcmwatchdog.cpp:66-76 |
| SDL3 hat einen Treiber für KMS und DRM | SDL src/video/kmsdrm/ |
| Overlay für das Root-Dateisystem und Schreibschutz der Startpartition | Raspberry Pi documentation computers/configuration/performance.adoc:83-90 |
C. Rohmaterial
Drei Recherchen liegen in englischer Sprache neben diesem Dokument. Jede nennt ihre Quellen mit Stand und Zeile.
previous-host-dependencies.md beschreibt, was Previous vom System braucht, Teil für Teil, mit der Zahl der Zeilen je Teil und einer Tabelle dessen, was ohne Linux ersetzt wird.
bare-metal-environments.md beschreibt den Start des Pi 5, Circle und circle-stdlib Punkt für Punkt und die übrigen Umgebungen ohne Betriebssystem mit ihrem Stand auf dem Pi 5.
bare-metal-precedents.md beschreibt die Emulatoren, die bereits ohne Linux auf dem Pi laufen, mit einer Vergleichstabelle.
circle-usb-audio-feedback-check.patch ist die Prüfung des Takts aus Abschnitt 8.3, als Patch gegen Circle in Commit 7a81e1b.