- Erfahrungsbericht aus einem Uni-Projekt, bei dem versucht wurde, das Betriebssystem Xv6 mit einer selbst entworfenen CPU auf Basis einer RISC-ISA und einem selbst entwickelten C-Compiler zu portieren
- Das Projekt wurde so durchgeführt, dass alle Bestandteile wie CPU-Design, Entwicklung des C-Compilers (Ucc) und Portierung von Xv6 selbst erstellt wurden
- Das Team stellte sich der Aufgabe, für den OS-Betrieb zentrale Hardware- und Softwarefunktionen wie Interrupts, virtuellen Speicher und Cache zu entwerfen
- Beim Portieren von Xv6 traten verschiedene Hürden wie mangelnde Portabilität, schwieriges Debugging und Cache-Bugs auf, die jedoch eigenständig gelöst wurden
- Schließlich gelang sogar die Ausführung von interaktiven Anwendungen wie SL, Minesweeper und 2048 sowie eines Ray-Tracing-Programms, was pädagogisch wie technisch ein großer Erfolg war
Projektüberblick
- Dieses Projekt ist eine der bekanntesten praktischen Aufgaben des Fachbereichs Informatik der University of Tokyo und legt den Schwerpunkt darauf, dass Studierende Erfahrungen mit CPU- und Hardware-Design, Compilerbau und dem Ausführen von Anwendungen sammeln
- Ziel des Projekts war es, die ISA einer selbst entworfenen CPU direkt auf einem FPGA zu implementieren, dafür eine C-Toolchain (Ucc) zu entwickeln und den Ansatz bis zur Portierung eines Betriebssystems wie Xv6 auszuweiten
- Der Großteil des Versuchs wurde als selbstgesteuertes Lernen durchgeführt
CPU-Experiment und Aufgabenstellung
- Teams aus 4 bis 5 Personen entwarfen jeweils eine neue CPU-Architektur, implementierten sie auf einem FPGA und entwickelten zudem einen Compiler für diese Architektur
- Nach dem Bau eines Compilers für ein OCaml-Subset gehörte die Ausführung eines Ray-Tracing-Programms zu den verpflichtenden Bewertungskriterien
- Wenn zusätzlich Zeit blieb, konnten eigene Herausforderungen definiert werden; einige Studierende führten erweiterte Experimente wie CPU-Beschleunigung, Multicore-Entwicklung oder das Ausführen von Musik bzw. Spielen durch
- Team Group 6 setzte sich insbesondere die Portierung eines Betriebssystems als Ziel; daraus entstand anschließend ein neues gemeinsames Team namens Group X
Das OS Xv6 und die Herausforderung der Portierung
- Als Portierungsziel wurde Xv6 (auf Unix v6 basierend, für x86) gewählt, das am MIT zu Lehrzwecken entwickelt wurde
- Xv6 ist zwar ein einfaches Unix-artiges Betriebssystem, bringt für die Ausführung auf realer Hardware aber verschiedene Probleme wie die Notwendigkeit eines C89-Compilers, spezieller Interrupts, Unterstützung virtueller Adressen und geringe Portabilität mit sich
- Xv6 setzt in C Eigenschaften von x86 voraus, etwa
char mit 1 Byte und int mit 4 Byte, was bei der Portierung viele Probleme verursachte
Entwicklung von Compiler und Toolchain (Ucc)
- In den bisherigen Praktika war die Entwicklung eines OCaml-Compilers der Standard, doch für den Betrieb von Xv6 wurde ein C89-Compiler benötigt, weshalb man sich für eine Eigenentwicklung entschied
- Auf Basis des Prototyps eines C-Compilers eines Teammitglieds wurde eine neue eigene Toolchain namens Ucc aufgebaut
- Nicht nur der Compiler, sondern auch ein einfacher Linker sowie Debug-Tools wurden selbst entworfen
Entwurf von CPU und Simulator
- Die CPU-Schaltung wurde in einer Hardwarebeschreibungssprache (HDL, z. B. Verilog / VHDL) entworfen und anschließend über Logiksynthese mit Vivado/Quartus auf ein reales FPGA gebracht
- Dieser wiederholte Logiksyntheseprozess dauerte sehr lange und brachte in der Praxis viel Wartezeit mit sich
- Zusätzlich zu den Grundfunktionen der CPU wurden auch für den OS-Betrieb nötige Hardware-Unterstützungen wie Interrupts, MMU und TLB separat entworfen
- Die fertige CPU erhielt den Namen GAIA
- Dem Simulator wurden reale Interrupts, virtuelle Adressübersetzung und Debugging-Werkzeuge hinzugefügt
Probleme im Portierungsprozess und ihre Lösung
- Wegen der geringen Portabilität von Xv6 kam es abhängig von CPU- und Compiler-Spezifikation zu Fehlverhalten
- Beispiel: Weil
char und int als 32 Bit definiert waren, wurden Pointer-Arithmetik und Stack-Struktur beschädigt
- Im Compiler Ucc wurde
char daraufhin auf 8 Bit angepasst
- Die Interrupt-Behandlung war ein besonders schwieriger Bereich, weshalb dem eigenen Simulator Debugging-Werkzeuge wie Disassembler und State-Dumps hinzugefügt wurden
- Das Problem des Cache-Aliasings entstand dadurch, dass GAIA virtuelle Adressen zur Cache-Indizierung verwendete, und wurde durch die Einführung von Page Coloring gelöst
Endergebnis: Ausführung von OS und Anwendungen
- Am 1. März gelang es schließlich, Xv6 sowohl im Simulator als auch auf der realen CPU-Hardware vollständig auszuführen
- Die Ausführung von interaktiven Apps wie einer eigenen Mini-curses-Bibliothek, dem Befehl SL, Minesweeper und 2048 war erfolgreich
- Insbesondere für 2048 wurde zusätzliche Unterstützung für nicht-kanonische Eingaben implementiert
- Durch Änderungen an Xv6 wurden sogar Funktionen entsprechend POSIX-artigem
ioctl und termios ergänzt
- Auch ein kleiner Assembler und ein mini vi wurden implementiert, wodurch praktisch eine „Echtzeit-Programmierumgebung“ entstand
- Auch das Ray-Tracing-Programm wurde auf dem Betriebssystem ausgeführt, womit das ursprüngliche Ziel des Praktikums sogar übertroffen wurde
Bedeutung des Projekts und spätere Beispiele
- Nach diesem Versuch führten mehrere nachfolgende Studierendengenerationen weiterhin verschiedene Experimente mit selbstgebauten CPUs und Betriebssystemen durch
- Beispielsweise wurde dies durch die Übernahme der RISC-V-ISA, eigene Betriebssysteme oder sogar das Ausführen von Linux erweitert
- Durch die praktische Erfahrung über den gesamten Hardware-/Software-Stack hinweg wurde das Verständnis von Algorithmen, Hardware-Software-Integration und Low-Level-Strukturen deutlich vertieft
- Zwar gibt es Kritik, dass eine „Neuerfindung des Rads“ ineffizient sei, doch der Lerneffekt und der Spaß am tatsächlichen Bauen seien sehr groß
Praktische Demo und Quellcode
- Unter GAIA CPU + Xv6 Demo lässt sich das System direkt ausprobieren
- Eine MIPS-Portierung ist hier als Open Source veröffentlicht
Fazit
- Mit der Lehre „Nichts vermittelt mehr Wissen, als es selbst zu bauen“ wird die Bedeutung integrierter Hardware-Software-Erfahrungen betont
- Auch spätere Studierende stellten sich immer neuen Zielen; langfristig hofft man, dass künftig Linux oder VMs auf einer eigenen ISA laufen könnten
- Der Bericht schließt mit den Namen der Projektmitglieder
4 Kommentare
Ich beneide ihn darum, so etwas an der Universität erleben zu können. Klingt nach einer Menge Spaß..
Das muss wirklich Spaß gemacht haben.
Ein wenig weiter nach unten scrollen…
Eine 8-Bit-CPU bauen…?
https://eater.net/8bit
Hacker-News-Kommentare
Das erinnert mich an ein Gruppenprojekt, das wir früher an der Uni zu dritt über drei Wochen gemacht haben. Unter mehreren Themen gab es auch die Möglichkeit, ein sehr grundlegendes Betriebssystem selbst zu bauen, also fragten wir die Professoren, ob wir MINIX3 auf den Raspberry Pi portieren dürften, und bekamen die Erlaubnis dafür (es schien machbar, weil es bereits einen ARM-Port von MINIX3 für das BeagleBoard gab).<br>Es war deutlich schwieriger als erwartet, und es tauchten technische Probleme auf, mit denen wir nie gerechnet hätten. Besonders mühsam war, dass der Raspberry Pi 3 im Hypervisor-Modus statt im Supervisor-Modus bootete, und die Genauigkeit der Raspberry-Pi-Emulation in QEMU war so schlecht, dass sie für OS-Entwicklung fast unbrauchbar war. Wir hingen eine ganze Woche an Low-Level-Hardware-Debugging, um eine Lösung zu finden. <br>Am Ende haben wir einen funktionierenden Port mit UART-, GPIO- und Framebuffer-Treibern gebaut und ihn erfolgreich auf Raspberry Pi 2 und 3 zum Laufen gebracht. Wir hielten die Präsentation auf echter Hardware, gaben per Shell-Skript ein Ramdisk-Image aus, überwachten GPIO-Pins, um zwischen Folien vor und zurück zu wechseln, und bedienten das Ganze direkt, indem wir die Pins mit einem Messer kurzschlossen. In Sachen Originalität war das eine mit Abstand großartige Präsentation, und ich glaube, ich habe das SD-Karten-Image immer noch irgendwo
Klingt nach einer großartigen Erfahrung<br>In dem Moment, als ihr vorgeschlagen habt, MINIX3 auf den Raspberry Pi zu portieren, könnten die Professoren schon damit gerechnet haben, dass ihr scheitert<br>Als die Genauigkeit der Raspberry-Pi-Emulation in QEMU schlecht war, habe ich die Strategie verfolgt, mein OS zuerst in QEMU zum Laufen zu bringen und dann auf der Hardware auf Glück zu hoffen. Das hat trotzdem ganz gut funktioniert<br>Mich würde interessieren, wie ihr das Debugging auf dem echten Raspberry Pi gemacht habt
Als ich hörte, dass ihr zum Kurzschließen der GPIOs ein Messer benutzt habt, musste ich daran denken, wie ich einmal auf einem ATX-Mainboard zwei Power-Pins kurzgeschlossen habe, um es ohne Power-Schalter zu starten<br>Aber euer Setup ist noch viel cooler. Gut gemacht
An der SFU habe ich vor 25 bis 30 Jahren etwas Ähnliches gemacht. Ich habe allerdings weder ein OS noch einen Compiler darauf gebracht, und es war auch kein Teamprojekt<br>Wenn dich solche Experimente interessieren, kann ich Turing Complete empfehlen, das gute Anleitungen und zugängliche Tools bietet. Man kann sich von ein paar Gattern bis zu einem echten Computer hocharbeiten. Community und Komponenten lassen sich ebenfalls teilen, und es gibt auch einen RiscV-Kern. Es macht wirklich Spaß, also probier es auf Steam aus
Wenn ich das sehe, wirkt es wie eine Spielversion von nand2tetris, mit dem ich früher viel Spaß hatte. Auch das ist eine Empfehlung, die einen Versuch wert ist
Dieser Beitrag erinnert mich irgendwie an ein ähnliches akademisches(?) Projekt. Soweit ich mich erinnere, gab es dort zumindest einen eigenen C-Compiler und ein eigenes OS. An den Namen erinnere ich mich nicht genau
Zur Referenz ein früherer verwandter Thread: Link zum früheren Beitrag
Wenn man CPU + Compiler + OS selbst baut, gibt es darunter überhaupt keine Plattform. Ich bin selbst die Plattform.<br>Ein Bug ist dann das Gesetz des Systems. Normalerweise debuggt man innerhalb von Abstraktionsschichten, die andere gebaut haben, aber hier definiert man sogar diese Regeln selbst. OP hat gewissermaßen seine eigenen Regeln debuggt
Wirklich beeindruckend. Arbeit im Low-End-Bereich ist meistens langweilig und kostet viel Zeit, besonders wenn essenzielle Werkzeuge wie ein Debugger fehlen
kprintf-Debugging gemacht hast, dann hast du das wahre Low-Level-Gefühl noch nicht erlebtMagic-1 und BMOW haben früher ebenfalls etwas Ähnliches gemacht<br>Mehr dazu auf homebrewcpu.com<br>Eine Liste von Seiten zu selbstgebauten CPUs gibt es auf homebrewcpuring.org
Jetzt ist wohl der Zeitpunkt gekommen, statt einer FPGA-Implementierung ins Halbleiterlabor zu rennen und sich eine CPU direkt fertigen zu lassen