Diosix entwickeln
Priorisiere Sicherheit > Sicherheit > Korrektheit > Wartbarkeit. Schreibe
idiomatisches Zig 0.17.0 und RISC-V-Assembler, das selbstdokumentierend, speichersicher
und streng begrenzt ist, sodass jede Änderung beim ersten Durchlauf reviewing-diosix
besteht, ohne Vorkommmit-Überarbeitung.
Kernauflagen
- Arbeitender, vollständiger & baubarer Code (Grundvoraussetzung): Jede Änderung muss
sowohl im Root-VM/Hypervisor-Build als auch in der Host-Unit-Test-Suite sauber kompilieren
(
./scripts/build.shund./scripts/build.sh test). Hinterlasse niemals kaputten Code, auskommentierteTODO-Platzhalter, simulierte Produktionspfade oder teilweise implementierte Funktionen. - Zeilen- & Dateigrenzen (In Unterordner komponentisieren, nie kürzen): Brich alle
Code- und Kommentare bei <= 80 Spalten um. Halte Quelldateien <= 500
Zeilen. Wenn eine Datei über 500 Zeilen hinauswächst, kürze niemals ihre Funktionalität
oder Tests; zerlege sie in einen dedizierten Unterordner (
panes/vm.zig,vm/run.zig,tests/gui.zig), statt flacheprefix_subname.zig-Dateien zu vermehren (panes_vm.zig,vm_run.zig,tests_gui.zig), und verbinde jedes Untermodul mit demtest-Block des Elternteils (_ = @import("vm/run.zig");). - Unterordner über Präfix-Unterstrich-Dateinamen & null Kopieren-Einfügen: Verwende
prägnante
snake_case-Dateinamen ohne redundante Projekt-, Verzeichnis- oder Geschwister-Präfixe (verwendeapi.zig,main.c,vm/info.zigundtests/nav.zig, niemalsdiosix_api.zig,diosix-alsa-init.c,vm_info.zigodertests_nav.zig). Dupliziere niemals gemeinsame Primitive (wieSpinlock, Seitenausrichtungs-Mathematik, Pfad-Traversal-Validatoren oder ABI Konstanten) über Module hinweg; importiere sie aushypervisor/interface/,hypervisor/core/atomic.zigodercommon.zig. - Idiomatische Verteilung: Schreibe niemals
if (std.mem.eql(...)) else if (...)Ketten für Befehle, Flags oder Konfigurationsschlüssel. Definiere einenum, parse mitstd.meta.stringToEnum(EnumType, slice)und verteile mitswitch. - Explizite Festbreiten-ABI-Typen, Kleinbuchstaben-Hex & benannte Bitmasken: Verwende
explizite Festbreiten-Typen (
u64,u32,u16,u8) in allen ABI/Hardware Structs (extern struct,packed struct) und 64-Bit-Gastregisterzuständen — niemalsusizeoder Cunsigned long. Kommentiere immer lokale Variablen, die aus@min/@maxinitialisiert werden, mit einem comptime-Literal (const w: usize = @min(n, 1280);), damit Zig keinen schmalen Integer-Typ (u11) ableitet, der später überläuft. Schreibe alle hexadezimalen Literale in Kleinbuchstaben (0xfff,0xffff_ffff, niemals0xFFF), und ersetze magische Bitmasken/Offsets ((vaddr & 0xfff) > 0xffc) durch benannte Konstanten und selbstdokumentierende Helfer (PAGE_OFFSET_MASK,crossesPageBoundary(vaddr, @sizeOf(u32))). - Dynamische Allokation über statisches Raten: Nur früher M-Mode-Boot-Code,
der vor der Heap-Initialisierung ausgeführt wird, darf feste statische Puffer verwenden. Sobald ein
Allokator verfügbar ist, allokiere und vergrößere Puffer dynamisch, anstatt feste Puffergrößen zu raten
(z.B. vermeide
var buf: [4096]u8). - Speicherbesitz & Bereinigung: Paare jede Allokation (
alloc,create,dupe,print,mmap) sofort mitdeferodererrdefer. Nullung freigegebener Gastseiten und kryptografischer Geheimnisse (std.crypto.secureZero). - Enterprise-Hypervisor-Isolation: Gerate niemals in Panik (panic) im M-Mode aufgrund von
Gast-Eingabe oder -Zustand; gib einen SBI-Fehler zurück oder beende den betroffenen Gast-
Teilbaum. Kopiere gemeinsamen Gastspeicher einmal (
@memcpy) in hypervisor-eigenen Speicher vor der Validierung, um Double-Fetch (TOCTOU) Schwachstellen zu verhindern. - Mechanismus im Code, Politik in Build/Run-Time-Konfiguration: Härte niemals
politikbezogene Einstellungen oder einstellbare Standardwerte in Zig-Code ein. Verschiebe einstellbare
Werte und Einstellungen in die Build-Zeit-Konfiguration (
build.zigOptionen /boot/hypervisor.conf) oder Laufzeit-Konfigurationsdateien (/etc/diosix/*.toml, haltekey = "value"auf einzelnen Zeilen <= 80 Spalten). - Baue Binärdateien & Images zur Build-Zeit, nicht on the fly in Zig: Vermeide
das Zusammenstellen von ELF-Binärdateien, Maschinencode-Shims oder Medienimages Wort für Wort zur
Laufzeit in Zig. Halte Shims in Assembly- oder Zig-Quelldateien, die während der Build-Zeit
kompiliert werden, verwende dedizierte Skripte zum Erstellen von Medienimages und platziere niemals
generierte Build-Ausgaben innerhalb von
tools/overlay-common/(verwende.zig-cache/overlay-dynamic/). - Kollokierte Unit-Tests & separate Integrationstests: Platziere Unit
testBlöcke innerhalb der Quellcodedatei, die sie testen (Rufestd.testing.refAllDecls(@This())auf). Platziere Multi-Komponenten-Integrationstests in dediziertentests/Verzeichnissen. - Rückwärtskompatibilität ohne Altlasten-Ansammlung: Bewahre Kompatibilität
für externe Verträge (SBI-Hypercall-ABI,
/dev/diosixioctls, dokumentiertedsxCLI-Befehle/JSON-Schemata und benutzerverfasste/etc/diosix/*.toml-Dateien), aber häufe niemals Multi-Pfad-Fallback-Arrays (DEFAULT_GUEST_CANDIDATES) für ko-versionierte interne Leitungen an. Wenn Produzent und Konsument gemeinsam in diesem Repository ausgeliefert werden, aktualisiere alle bauminternen Produzenten, Konsumenten und Tests atomar, um einen einzigen kanonischen Pfad oder Symbol zu verwenden, und behandle persistente Datenträgerlayout-Upgrades einmal an der Boot/Install-Grenze, anstatt historische Pfade für immer abzufragen. - Bei Unsicherheit anhalten und den Hauptwart fragen: Rate niemals über Architekturentscheidungen, mehrdeutige Anforderungen oder fehlende Subsystem-Fähigkeiten. Halte an und frage den Hauptwart, bevor du fortfährst.
M-Mode vs. U-Mode-Ausführungsumgebungen
| Aspekt | M-Mode-Hypervisor (hypervisor/) | U-Mode-Tooling (tools/) |
|---|---|---|
| Ziel | riscv64-freestanding-none | riscv64-linux-musl (oder Host in Tests) |
| Vor-Heap-Boot | Statische Per-Core-Platten (0..31) in entry.s | N/A (OS-Prozessumgebung bereit bei main) |
| Allokator | Per-Core pcore.this().allocator.allocator() | std.heap.SafeAllocator / page_allocator / ArenaAllocator |
| Absturz-Politik | Niemals bei Gast-Eingabe in Panik geraten; betroffene Gast-VM isolieren & beenden | Beschreibenden Fehler und sauberen Exit-Code zurückgeben |
| Hardware-Zugriff | Direktes CSR/MMIO (muss mit if (is_test) für Host-Unit-Tests geschützt werden) | /dev/diosix ioctls (api.zig), DRM/evdev, Linux-Syscalls |
Fokussierte Referenzleitfäden
Lies die relevante Referenzdatei, bevor du Code schreibst oder änderst:
- Zig 0.17.0 Idiome & Builtins:
Aktuelle Zig 0.17 Syntax (
@backingInt,@splat,allocator.print,SafeAllocator,stringToEnum,@ptrCastfürextern struct, Festbreiten- ABI-Typen,@minTypannotationen, 80-Spalten-Formatierung mit nachfolgenden Kommas, und Build-Cache-Reinheit). - Speicherverwaltung & dynamische Puffer:
M-Mode vs. U-Mode Allokator-Muster, dynamisches Pufferwachstum,
defer/errdeferDisziplin, Geheimnis-Nullung und Aus-Zeiger-Initialisierung. - Architektur & TigerStyle: Vollständige Feature-Implementierung, modulare Dateiaufteilung ohne Verlust von Unit-Tests, null Kopieren-Einfügen Duplikation, begrenzte Schleifen, Assertions-Paarung und Overlay/Konfigurations-Hygiene.
- RISC-V & Enterprise-Hypervisor: RV64-Assembly-Konventionen, CSR-Mocking, Explosionsradius-Eindämmung, Double-Fetch- Präventionsmuster, IRQ-sichere Spinlock-Reihenfolge und G-Stage/PMP-Isolation.