- Ein interaktives Tutorial, mit dem man RISC-V-Assembly Schritt für Schritt über einen im Webbrowser lauffähigen Emulator lernen kann; inspiriert von Nick Morgans Easy 6502
- Behandelt die 45 Basisbefehle des RV32I_Zicsr-Befehlssatzes sowie die Kernkonzepte der privilegierten Architektur und vermittelt einen für Compiler-Ziele hinreichend vollständigen Befehlssatz
- Bietet Grundlagen der Assembly-Programmierung wie Arithmetik-/Logikoperationen, Verzweigungen/Sprünge, Speicherzugriffe, Funktionsaufrufkonventionen und Stack-Verwaltung zusammen mit Praxisbeispielen
- Erklärt mit realem Code den Wechsel zwischen Privilegstufen zwischen Machine Mode und User Mode, die Ausnahmebehandlung sowie die Manipulation von CSRs (Control and Status Registers)
- Das Endziel des Tutorials ist das eigenständige Schreiben eines winzigen Betriebssystems mit Unterstützung für System Calls und Ausnahmebehandlung, sodass sich der gesamte Ablauf der Low-Level-Entwicklung mit RISC-V nachvollziehen lässt
Aufbau des Tutorials und wichtigste Lerninhalte
Grundlegende Befehle und Prozessorkonzepte
- Prozessorzustand: Verständnis von Program Counter (
pc), 31 allgemeinen Registern (x1~x31) und dem speziellen Zero-Register (x0)
- Arithmetische Befehle: Lernen von Addition/Subtraktion und dem Verhalten bei Overflow mit
add, addi, sub usw.
- Bitoperationen: Übungen zu logischen Bitoperationen und Shift-Befehlen wie
and, or, xor, sll, srl, sra
- Vergleichsbefehle: Umsetzung von Logik für vorzeichenbehaftete/vorzeichenlose Ganzzahlvergleiche und Bedingungen mit
slt, sltu usw.
Kontrollfluss und Speicher
- Verzweigungen und Sprünge: Mechanismen für bedingte/unbedingte Verzweigungen und Funktionsaufrufe mit
beq, bne, blt, jal, jalr usw.
- Speicherzugriff: Load-/Store-Operationen für Word, Halfword und Byte mit
lw, sw, lb, lh, sb, sh
- Memory-Mapped I/O: Verständnis dafür, wie über Lese-/Schreibzugriffe auf bestimmte Adressen mit externen Geräten kommuniziert wird
- Positionsunabhängiger Code: Techniken zum Schreiben von relocatablem Code mit dem
auipc-Befehl und PC-relativer Adressierung
Funktionen und Aufrufkonventionen
- Register-Aliasse: Rollen von
a0~a7 (Argumente), s0~s11 (gesichert), t0~t6 (temporär), ra (Rücksprungadresse), sp (Stack Pointer) usw.
- Stack-Verwaltung: Muster zum Sichern von Registern beim Funktionseintritt, Reservieren/Freigeben von Stack-Speicher sowie zum Bewahren und Wiederherstellen der Rücksprungadresse
- Rekursive Funktionen: Praxis mit rekursiven Aufrufen und Stack-Frame-Verwaltung anhand einer Fibonacci-Implementierung
Privilegierte Architektur und Betriebssystem
- Privilegstufen: Unterschiede zwischen Machine Mode (Level 3) und User Mode (Level 0) sowie deren Isolationsmechanismen
- CSR-Befehle: Lesen/Schreiben von Kontrollregistern und Manipulation von Bitfeldern mit
csrrw, csrrs, csrrc usw.
- Ausnahmebehandlung: Prüfen von Ausnahmeinformationen und Schreiben von Handlern mit den CSRs
mcause, mepc, mtval, mstatus
- Moduswechsel: Eintritt in den User Mode und Rückkehr mit dem
mret-Befehl sowie Context Switching mit mscratch
Abschlussprojekt: winziges OS
- Implementierung von System Calls: Trap von User Mode in Machine Mode mit dem
ecall-Befehl, um putchar-/exit-Funktionen bereitzustellen
- Sichern/Wiederherstellen von Registern: Vollständige Struktur eines Trap-Handlers, der alle allgemeinen Register auf dem Stack sichert und restauriert
- Logik der Ausnahmebehandlung: Bestimmung der Ausnahmeursache mit
mcause, Dispatch nach System-Call-Nummer (a7) und Ausgabe von Fehlermeldungen
- Ausführbarer Code: Vollständiger Code für Einstieg und Rückkehr des OS-Kernels, direkt im Web-Emulator ausführbar
Referenzmaterialien und Lizenz
- Tutorial und Code stehen vollständig unter CC0 Public Domain oder der 0-clause BSD-Lizenz
- Original und Code-Repository: https://github.com/dramforever/easyriscv
- Für das Lernen von RISC-V geeignet für Bildung, Forschung und den Aufbau von Simulationsumgebungen
Noch keine Kommentare.