Lyx OS – IOFS: Island & Ocean File System
IOFS ist das native Dateisystem von Lyx OS. Es ersetzt FAT32 als primären Speicher und ist von Grund auf für drei Anforderungen gebaut: Zero-Load-Ausführung (LBF-Binaries laufen direkt aus dem Speicher, ohne Kopieren), graphbasierte Abhängigkeitsverwaltung (Pages sind Knoten, Abhängigkeiten sind typisierte Kanten) und semantische Suche (jede Page kann mit Embeddings annotiert werden).
→ LBF-Binärformat · Syscall-ABI 0x0C00 · Architektur · Übersicht
1. Die Metapher: Ocean, Islands, Pages
┌──────────────────────────────────────────────────────────────┐
│ OCEAN (gesamtes Block-Device) │
│ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Island "system" │ │ Island "tools" │ ... │
│ │ │ │ │ │
│ │ Page 0x0001 │ │ Page 0x4A01 │ │
│ │ Page 0x0002 ────┼──┼─► Page 0x4A02 │ (Graph-Kante) │
│ │ ... │ │ ... │ │
│ └──────────────────┘ └──────────────────┘ │
└──────────────────────────────────────────────────────────────┘
| Begriff | Bedeutung |
|---|---|
| Ocean | Das gesamte Block-Device. Enthält alle Islands als logische Namensräume. |
| Island | Benannter Container für zusammengehörige Pages, z.B. system, tools, ai-models. Entspricht grob einem Dateisystem-Volume oder einer Datenbank. |
| Page | Kleinste Adressierungseinheit: exakt 4096 Bytes. Jede Page trägt einen 32-Byte-Header mit Typ, CRC32C-Prüfsumme und LPID. |
| LPID | *Logical Page ID* — eine 64-Bit-Kennung, die eine Page eindeutig im Ocean identifiziert. Entspricht dem logischen Block-Slot (LBA-Block). |
2. Page-Aufbau
Jede IOFS-Page ist exakt 4096 Bytes groß. Der Page-Header belegt die ersten 64 Bytes (0x00–0x3F), das Payload beginnt bei Offset 0x40:
Offset Größe Feld Beschreibung
────── ───── ──────────────── ─────────────────────────────────────────────
0x0000 4 magic "LYX!" (0x4C 0x59 0x58 0x21)
0x0004 1 type Page-Typ (IOFS_TYPE_*)
0x0005 1 flags Page-Flags (IOFS_FLAG_*)
0x0006 2 edge_offset (LE) Byte-Offset der Kanten-Liste in der Page (0x0040 = kein Kantenblock)
0x0008 8 lpid (LE) Logical Page ID dieser Page
0x0010 2 payload_size (LE) Größe der Nutzdaten in Bytes (max. 4032)
0x0012 2 (reserviert) Muss 0 sein
0x0014 4 crc32c (LE) CRC32C-Castagnoli über die gesamte 4096-Byte-Page (Feld beim Berechnen auf 0 gesetzt)
0x0018 8 cont_lpid (LE) Continuation-LPID (0 = keine Fortsetzung; für Pages > 4032 Bytes)
0x0020 32 (reserviert) Muss 0 sein
0x0040 4032 payload Nutzdaten (ab Offset 64)
Page-Typen
| Wert | Konstante | Beschreibung |
|---|---|---|
| 1 | IOFS_TYPE_META | Metadaten-Page (Verzeichnis, Root-Node, Index-Segmente) |
| 2 | IOFS_TYPE_DATA | Allgemeine Nutzdaten (Datei-Inhalt, KV-Cache, Embeddings) |
| 3 | IOFS_TYPE_EMBED | Embedding-Vektor-Page (KI-Subsystem, M7+) |
| 4 | IOFS_TYPE_EDGE_LIST | Kanten-Listen-Page (WP05, Graph-Layer) |
| 5 | IOFS_TYPE_NAME_STORE | Name-Store-Page (WP07, Named Nodes, LPID=2) |
con IOFS_TYPE_META: int64 := 1;
con IOFS_TYPE_DATA: int64 := 2;
con IOFS_TYPE_EMBED: int64 := 3;
con IOFS_TYPE_EDGE_LIST: int64 := 4; // WP05
con IOFS_TYPE_NAME_STORE: int64 := 5; // WP07
Page-Flags
| Wert | Konstante | Beschreibung |
|---|---|---|
| 1 | IOFS_FLAG_IMMUTABLE | Page darf nach dem Schreiben nicht verändert werden (z.B. Root-Node) |
| 2 | IOFS_FLAG_EPHEMERAL | Page gilt als temporär und kann beim nächsten Kompaktierungszyklus entfernt werden |
con IOFS_FLAG_IMMUTABLE: int64 := 1;
con IOFS_FLAG_EPHEMERAL: int64 := 2;
Unterscheidung IOFS-Page vs. LBF-Genesis: Beide tragenLYX!an Byte 0. Unterscheidung erfolgt über Byte0x0004: LBF-Genesis hat dort dieformat_version(0x01 = v1.0, 0x02 = v1.1); IOFS-Pages haben dortIOFS_TYPE_META(1) bisIOFS_TYPE_EMBED(3) — semantisch gleiche Werte, aber im Context (Superblock vorhanden = IOFS-Volume) eindeutig interpretierbar.
3. LIP-Adressierung: LPID → LBA
Die Kernleistung von IOFS ist die O(1)-Übersetzung eines LPIDs in eine physische LBA (Logical Block Address). Der Kernel hält eine kompakte In-Memory-Tabelle, die LIP-Tabelle (*Logical Island Page*):
lip_get(lpid) → lba O(1) — direkter Array-Zugriff
lba × 4096 → Byte-Offset auf dem Block-Device
Im Zero-Load-Modus (→ LBF-Format, Abschnitt 6) trägt der Kernel diese LBAs direkt als physische Adressen in die CPU-Page-Tables (CR3) ein. Die CPU greift auf LBF-Code-Pages zu, als wären sie RAM — ohne eine einzige Kopie.
// Kernel-internes API (nicht als Syscall exponiert):
var lba: int64 := lip_get(block_lpid);
// pte.phys_addr = lba × 4096
// pte.flags = PROT_READ | PROT_EXEC (für .text-Pages)
4. Graph-Kanten
Jede Page kann als Knoten im Kernel-Wissensgraphen (→ Syscalls 0x080F–0x0812) registriert werden. IOFS definiert zwei eingebaute Kanten-Typen für die LBF-Integration:
| Kanten-Typ | Konstante | Bedeutung |
|---|---|---|
0xB001 | IOFS_EDGE_LBF_CHAIN | Genesis-Block → Block 1 → Block 2 → … (Code-Seiten-Kette) |
0xD001 | IOFS_EDGE_LBF_DEP | Genesis-Block → Dependency-Genesis (Bibliotheks-Abhängigkeit) |
con IOFS_EDGE_LBF_CHAIN : int64 := 0xB001
con IOFS_EDGE_LBF_DEP : int64 := 0xD001
Weitere Kanten-Typen werden von höheren Schichten vergeben (z.B. semantische Ähnlichkeit durch den AI-Subsystem-Layer in M7+). Die Kanten werden im Kernel-Wissensgraph (sys_graph_*) gespeichert — IOFS selbst speichert nur die rohen Page-Daten.
5. Hash-Index
IOFS führt einen Hash-Index über alle Genesis-Pages (Typ 0x04). Schlüssel ist der SHA-256-Hash der Quelldateien (source_sha256 aus dem LBF-Genesis-Header), Wert ist der LPID der entsprechenden Page.
Anwendung: Der LBF-Loader löst DEP_HASH_GRAPH-Einträge (TLV 0x02) ohne Verzeichnis-Traversierung auf — er berechnet den SHA-256 der Abhängigkeit und schlägt direkt im Hash-Index nach. Kein symbolisches Linking, keine Pfad-Suche.
import-Auflösung:
sha256(dep.source) → lip_index_lookup() → lpid → lba
kein ld.so, kein PATH-Scan, kein symbolisches Linking
6. Omni-Ingest
Beim Import eines LBF-Binaries via lbf_import läuft der Omni-Ingest-Prozess:
- LBF-Blöcke werden als IOFS-Pages gespeichert (Typ
0x04für Genesis,0x02für Code-/Daten-Pages) - Der
HUMAN_INTENT-Text (TLV 0x01 aus dem Genesis-Block) wird durch das KI-Subsystem in einen Embedding-Vektor umgewandelt - Der Embedding-Vektor wird an die Genesis-Page annotiert (
sys_sem_annotate) - Die Page wird im Kernel-Wissensgraph registriert (
sys_graph_node_create) - Graph-Kanten werden zwischen den LBF-Blöcken gewoben
Nach dem Ingest ist das Programm über sys_ai_search (semantische Ähnlichkeit) und sys_timeline_query (zeitbasiert) auffindbar — ohne dass der User den genauen Dateinamen kennen muss.
lbf_import main.lbf --into-island="tools"
→ IOFS-Pages anlegen
→ Omni-Ingest: Embedding + Graph-Registrierung
→ Hash-Index aktualisieren
7. Panic-Sandbox
Die Panic-Sandbox ist ein IOFS-Modus für die Vertrauenskette des LBF-Loaders (→ LBF-Format, Abschnitt 5).
sys_iofs_sandbox_enter(CAP_ADMINerforderlich) aktiviert den Modus: IOFS verweigert alle Schreiboperationen außer dem Aktualisieren der Compiler-Blacklist- In diesem Modus können kompromittierte Compiler-UUIDs sicher zur Blacklist hinzugefügt werden, ohne dass ein laufender Angriff die Liste manipulieren kann
sys_iofs_sandbox_exitverlässt den Modus
Beim LBF-Import prüft der Kernel automatisch: Ist die compiler_instance_sn (UUID aus dem Genesis-Block) in der Blacklist? Falls ja, wird der Import abgelehnt — Schicht 3 der 5-Schichten-Vertrauenskette.
8. Kompaktierung
IOFS ist ein Append-Only-System: gelöschte oder veraltete Pages werden nicht sofort überschrieben, sondern als IOFS_PAGE_FREE markiert. Ein periodischer oder manueller Kompaktierungszyklus defragmentiert das Volume:
var mount_fd: int64 := ...;
// region_hint = 0: gesamtes Volume kompaktieren
var freed_pages: int64 := 0;
var err: int64 := 0;
// (err, freed_pages) := syscall(SYS_IOFS_COMPACT, mount_fd, 0);
sys_iofs_compact (0x0C01) gibt die Anzahl der zurückgewonnenen Pages zurück. Der Kernel kann diesen Zyklus auch automatisch im Hintergrund auslösen (konfigurierbar über IofsOpts beim Mount).
9. On-Disk-Layout (WP01+WP09, implementiert)
Das IOFS-Volume auf einem 64-MB-Datenträger ist in fünf feste Bereiche aufgeteilt. Alle Werte aus kernel/iofs_alloc.lyx:
Page Bereich Seiten Beschreibung
──────── ─────────────── ────── ─────────────────────────────────────
0 Superblock 1 "IOFS"-Magic + Layout-Konstanten
1 Root Node 1 LPID=1, "LYX!"-Magic, Type=Meta, Flag=Immutable
2–131 Checkpoint Slot A 130 1 Header + 1 Bitmap + 128 LIP-Pages (aktiv, seq=1)
132–261 Checkpoint Slot B 130 identische Struktur, beim mkfs genullt (inaktiv)
262–325 WAL 64 Write-Ahead-Log, beim mkfs genullt
326–16383 Ocean 16058 allocierbar (≈ 62 MB)
Konstanten (kernel/iofs_alloc.lyx)
con IOFS_TOTAL_PAGES: int64 := 16384; // 64 MB / 4096 B
con IOFS_SECTORS_PER: int64 := 8; // 4096 / 512 → LBA = page_idx * 8
con IOFS_MAX_LPID: int64 := 65536;
con IOFS_BITMAP_BYTES: int64 := 2048; // ceil(16384 / 8)
con IOFS_PAGE_SUPER: int64 := 0;
con IOFS_PAGE_ROOT: int64 := 1;
con IOFS_SLOT_LIP_PAGES: int64 := 128; // MAX_LPID*8 / 4096
con IOFS_SLOT_PAGES: int64 := 130; // 1 Header + 1 Bitmap + 128 LIP
con IOFS_PAGE_SLOT_A: int64 := 2;
con IOFS_PAGE_SLOT_B: int64 := 132;
con IOFS_WAL_PAGES: int64 := 64;
con IOFS_PAGE_WAL_START: int64 := 262;
con IOFS_PAGE_WAL_END: int64 := 325;
con IOFS_PAGE_OCEAN_START: int64 := 326;
con IOFS_PAGE_OCEAN_END: int64 := 16383;
con IOFS_OCEAN_PAGES: int64 := 16058; // 16383 − 326 + 1
Superblock (Page 0)
Offset Größe Feld Wert bei mkfs
────── ───── ──────────────── ─────────────────────────────────────────
+0 4 magic "IOFS" (0x49 0x4F 0x46 0x53)
+4 1 version_major 1
+5 1 version_minor 0
+8 8 total_pages 16384
+16 8 max_lpid 65536
+24 8 ocean_start 326
+32 8 ocean_end 16383
+40 8 slot_a 2
+48 8 slot_b 132
+56 8 wal_start 262
+64 8 wal_end 325
+72 8 slot_pages 130
+80 8 wal_pages 64
+88 8 sectors_per_page 8
+96 8 ocean_pages 16058
Checkpoint-Slot-Header
Jeder Slot beginnt mit einer Header-Page (Offset 0 im Slot):
Offset Feld Beschreibung
────── ──────────── ────────────────────────────────────────────
+0 valid (1B) 1 = aktiv, 0 = inaktiv
+8 seq lo (1B) Sequenz-Nummer (32-Bit LE, über Bytes +8..+11)
+16 bitmap_pages 1 (immer 1 Bitmap-Page)
+20 lip_pages lo 128 (LE, über Bytes +20..+21)
Crash-Atomarität: der Slot-Header wird zuletzt geschrieben. Bitmap + LIP-Pages werden vollständig auf Disk gebracht, bevor valid=1 gesetzt wird. Bei Absturz vor dem Header bleibt der Slot mit valid=0 ungültig.
WP04: Ab WP04 enthält der Slot-Header zusätzlichwal_seq_at_checkpointbei Offset +24 (uint32 LE).IofsCheckpointschreibt dort den aktuellenWalSeq()-Wert, bevor der Header auf Disk kommt.IofsMountDiskliest diesen Wert und übergibt ihn anWalInit(), damitWalReplayweiß, ab welcher Sequenznummer die WAL-Einträge nach dem letzten Checkpoint relevant sind.
LIP-Pages (Logical Island Page Table)
128 LIP-Pages pro Slot bilden die LPID→page_idx-Tabelle:
lip_page[k] enthält int64-Einträge für LPID k*512 … k*512+511
Eintrag j: page_idx des physischen Blocks für LPID (k*512+j)
0 = nicht alloziert
Beim mkfs: LIP-Page 0 (Slot-Offset +2):
Byte 0..7 = 0 (LPID 0 = kein Root)
Byte 8..15 = 1 (LPID 1 = Root Node, page_idx=1)
Rest = 0
Alle weiteren LIP-Pages = 0
10. CRC32C-Integrität (WP03, kernel/iofs_alloc.lyx)
WP03 ergänzt eine vollständige CRC32C-Prüfsummen-Engine für alle IOFS-Pages.
Algorithmus
Castagnoli CRC32C mit reflektiertem Polynom 0x82F63B78. Die Lookup-Tabelle (256 × uint32 = 1024 Bytes) wird beim ersten Aufruf von IofsAllocInit einmalig per mmap alloziert und befüllt (Guard: crc32c_table != 0).
CRC-Berechnung (Castagnoli):
c = 0xFFFFFFFF
for each byte b:
idx = (c XOR b) & 0xFF
c = (c >> 8) XOR table[idx]
return (c XOR 0xFFFFFFFF) & 0xFFFFFFFF
Funktionen (kernel/iofs_alloc.lyx)
| Signatur | Beschreibung |
|---|---|
IofsCrc32c(data, len): int64 | Öffentlicher CRC32C-Berechner für beliebige Daten. Gibt 32-Bit-CRC als int64 zurück. |
IofsPageHasMagic(buf): bool | Prüft ob buf[0..3] == „LYX!“ (0x4C 0x59 0x58 0x21). |
IofsPageSetCrc(buf): void | Nullt Bytes 0x14–0x17 des Puffers, berechnet CRC32C über alle 4096 Bytes, schreibt Ergebnis (LE) zurück an 0x14. |
IofsPageVerifyCrc(buf): bool | Liest gespeicherten CRC (0x14–0x17), nullt das Feld, berechnet neu, vergleicht; stellt Feld danach immer wieder her. Gibt true wenn gleich. |
Integration
| Aufrufstelle | Verhalten |
|---|---|
IofsAllocInit(disk_id) | Ruft crc32c_init() auf (einmalig, idempotent) |
IofsMkfs — Root-Node (p1) | IofsPageSetCrc(buf) vor dem Schreiben |
IofsWriteLpid(lpid, buf) | Wenn IofsPageHasMagic(buf): IofsPageSetCrc(buf) automatisch — jede LYX!-Page erhält beim Schreiben eine aktuelle Prüfsumme |
IofsReadLpid(lpid, buf) | Wenn IofsPageHasMagic(buf) und !IofsPageVerifyCrc(buf): return false — CRC-Fehler → Leseoperation schlägt fehl |
Hinweis: Nur Pages mit „LYX!“-Magic werden geprüft. Superblock (Page 0) und WAL-Pages tragen kein „LYX!“-Magic und werden nicht via CRC verifiziert.
11. Block-Allocator (WP01, kernel/iofs_alloc.lyx)
Der Block-Allocator verwaltet eine In-RAM-Bitmap (2048 Bytes) über alle 16384 Pages.
Initialisierung
IofsAllocInit(disk_id) markiert die 326 reservierten Pages (p0–p325) als belegt, Ocean-Pages (p326–p16383) als frei. Legt den Hint auf IOFS_PAGE_OCEAN_START.
Funktionen
| Signatur | Beschreibung |
|---|---|
IofsAllocInit(disk_id): void | Bitmap allozieren + initialisieren. Muss vor IofsAllocPage/IofsFreePageIdx gerufen werden. |
IofsAllocPage(): int64 | Nächste freie Ocean-Page allozieren (Bitmap-Bit setzen). Zwei-Pass-Suche: Hint→End, dann Start→Hint-1. Gibt page_idx zurück; -1 wenn voll. |
IofsFreePageIdx(page_idx): bool | Ocean-Page freigeben (Bitmap-Bit löschen). Gibt false bei ungültigem Index oder Double-Free. |
IofsCountFree(): int64 | Lineare Bitmap-Zählung aller freien Ocean-Pages (Diagnose). |
IofsIsReady(): bool | true nach IofsAllocInit. |
IofsGetBitmap(): int64 | Zeiger auf die In-RAM-Bitmap. |
IofsGetDiskId(): int64 | Disk-ID des aktuell initialisierten Volumes. |
Low-Level-I/O
| Signatur | Beschreibung |
|---|---|
IofsWritePage(disk_id, page_idx, buf): int64 | Schreibt 4096 Bytes (8×512-Byte-Sektoren) auf Disk. LBA = page_idx × 8. |
IofsReadPage(disk_id, page_idx, buf): int64 | Liest 4096 Bytes (8×512-Byte-Sektoren) von Disk. |
12. IofsMkfs — Formatierungssequenz
IofsMkfs(disk_id) (→ VfsMkfsIofs → Syscall 155 = sys_mkfs_iofs) schreibt das komplette IOFS-Volume in dieser Reihenfolge:
IofsAllocInit(disk_id)— Bitmap aufbauen- Superblock (Page 0): „IOFS“-Magic + alle Layout-Konstanten
- Root Node (Page 1): „LYX!“-Magic,
IOFS_TYPE_META,IOFS_FLAG_IMMUTABLE, LPID=1, payload=„IOFS_ROOT_v1.1“ (14 Bytes bei Offset 0x40) - WAL (Pages 262–325): alle Pages genullt
- Checkpoint Slot A (Pages 2–131): Bitmap (p3), LIP-Page 0 mit LPID-1→p1 (p4), LIP-Pages 1–127 genullt (p5–p131), Header zuletzt (p2, valid=1, seq=1)
- Checkpoint Slot B (Pages 132–261): vollständig genullt (Header valid=0)
Aufruf aus Ring-3:
import bsys;
// ...
var rc: int64 := SysMkfsIofs(disk_id); // 0 = OK, -1 = Fehler
Aufruf als Shell-Tool:
> mkfs_iofs 1
mkfs_iofs: formatting disk 1 as IOFS... OK
p0 Superblock
p1 Root node (LPID=1)
p2-131 Checkpoint slot A (1 header + 1 bitmap + 128 LIP pages)
p132-261 Checkpoint slot B (inactive, zeroed)
p262-325 WAL (64 pages, zeroed)
p326-16383 Ocean (16058 free pages)
13. WP02: Mount, Read, Write, Checkpoint (kernel/iofs_rw.lyx)
WP02 baut auf dem Block-Allocator (WP01) auf und liefert die vollständige LPID-basierte Lese-/Schreibschnittstelle sowie crash-atomare Checkpoints.
In-RAM-Strukturen
| Variable | Typ | Beschreibung |
|---|---|---|
iofs_lip | int64 (Ptr) | LIP-Tabelle: 65536 Einträge × 2 Bytes = 128 KB. LIP[lpid] = physischer page_idx (uint16 LE). 0 = nicht gemappt. |
iofs_active_slot | int64 | IOFS_PAGE_SLOT_A (2) oder IOFS_PAGE_SLOT_B (132) |
iofs_slot_seq | int64 | Sequenz-Nummer des aktiven Slots (steigt bei jedem Checkpoint) |
iofs_dirty | bool | true wenn LIP seit letztem Checkpoint verändert wurde |
Kernel-API (kernel/iofs_rw.lyx)
| Signatur | Beschreibung |
|---|---|
IofsMountDisk(disk_id): bool | Aktiven Checkpoint-Slot bestimmen (höchste seq, valid=1; bei Gleichstand Slot A bevorzugt). Bitmap + 128 LIP-Pages in RAM laden. |
IofsReadLpid(lpid, buf): bool | LIP-Lookup → physische Page lesen. lpid muss ≥ 1 und gemappt sein. |
IofsWriteLpid(lpid, buf): int64 | Neue Ocean-Page allozieren, vollständig formatierten 4096-Byte-Puffer schreiben, LIP aktualisieren, alte Page freigeben. Gibt neue page_idx zurück; -1 bei Fehler. |
IofsNewPage(type_, flags, payload, psize): int64 | Freien LPID-Slot suchen (IofsAllocLpidSlot), Page-Header aufbauen (Magic, Type, Flags, edge_offset=0x40, LPID, payload_size), Payload ab Offset 0x40 kopieren, via IofsWriteLpid schreiben. Gibt neuen LPID zurück; 0 bei Fehler. |
IofsFreeByLpid(lpid): bool | Physische Page freigeben + LIP-Eintrag löschen. LPID 1 (Root) ist geschützt. |
IofsCheckpoint(): bool | Crash-atomarer Dual-Slot-Flip: (1) Bitmap → inaktiver Slot +1, (2) 128 LIP-Pages → inaktiver Slot +2–+129, (3) Slot-Header mit valid=1 und seq+1 zuletzt schreiben. Swappt iofs_active_slot. |
IofsUnmount(): bool | Falls iofs_dirty: IofsCheckpoint() aufrufen. LIP-Tabelle freigeben. |
IofsLipGet(lpid): int64 | LPID → physischer page_idx (bounds-checked, 0 = nicht gemappt). |
IofsAllocLpidSlot(): int64 | Ersten freien LPID ≥ 2 suchen (LPID 0 = null, 1 = Root). |
IofsCountMapped(): int64 | Anzahl belegter LPIDs (Diagnose, lineare Suche). |
IofsIsMounted(): bool | true wenn LIP-Tabelle geladen. |
IofsActiveSlot(): int64 | Aktueller aktiver Slot-Start-Page. |
IofsSlotSeq(): int64 | Aktuelle Sequenz-Nummer. |
IofsIsDirty(): bool | true wenn ungespeicherte Änderungen vorhanden. |
Syscall-Binding (156–164)
| Nr | Name | Argumente | Rückgabe | Beschreibung |
|---|---|---|---|---|
| 156 | sys_iofs_mount | disk_id | 0 oder -1 | Checkpoint laden, LIP (128 KB) + Bitmap in RAM |
| 157 | sys_iofs_read_lpid | lpid, user_buf | 0 oder -1 | Page via LPID lesen (LIP→page_idx→DiskRead, user_buf muss 4096 Bytes groß sein) |
| 158 | sys_iofs_write_lpid | lpid, user_buf | page_idx oder -1 | Neue Ocean-Page allozieren, schreiben, LIP updaten, alte freigeben |
| 159 | sys_iofs_new_page | type, flags, payload_uva, psize | LPID oder 0 | LPID allozieren + Header bauen + schreiben (psize ≤ 4032) |
| 160 | sys_iofs_free_lpid | lpid | 0 oder -1 | Physische Page freigeben + LIP-Eintrag löschen (LPID 1 geschützt) |
| 161 | sys_iofs_checkpoint | — | 0 oder -1 | Dual-Slot-Flip: inaktiver Slot ← aktueller Stand (crash-atomar) |
| 162 | sys_iofs_unmount | — | 0 oder -1 | Checkpoint falls dirty, LIP-Tabelle freigeben |
| 163 | sys_iofs_lip_get | lpid | page_idx oder 0 | LPID→physischer page_idx (0 = nicht gemappt) |
| 164 | sys_iofs_info | out_buf_uva | 0 oder -1 | 64-Byte-Status-Buffer füllen (siehe unten) |
IofsInfo-Buffer (64 Bytes)
+0 (int64) mounted 1 = gemountet, 0 = nicht gemountet
+8 (int64) free_pages Anzahl freier Ocean-Pages
+16 (int64) mapped Anzahl belegter LPIDs
+24 (int64) active_slot IOFS_PAGE_SLOT_A (2) oder IOFS_PAGE_SLOT_B (132)
+32 (int64) seq Aktuelle Checkpoint-Sequenz-Nummer
+40 (int64) dirty 1 = ungespeicherte Änderungen vorhanden
+48 (int64) wal_head Nächster WAL-Schreib-Index (0–8191, zirkulär; WP04)
+56 (int64) wal_seq Nächste WAL-Sequenznummer (monoton ≥ 1; WP04)
Ring-3-Wrapper (bsys.lyx / bsys_vega.lyx)
SysIofsMount(disk_id): int64 // nr=156
SysIofsReadLpid(lpid, buf): int64 // nr=157; buf muss phys. Adresse sein
SysIofsWriteLpid(lpid, buf): int64 // nr=158
SysIofsNewPage(type_, flags, payload, psize): int64 // nr=159
SysIofsFreeLpid(lpid): int64 // nr=160
SysIofsCheckpoint(): int64 // nr=161
SysIofsUnmount(): int64 // nr=162
SysIofsLipGet(lpid): int64 // nr=163
SysIofsInfo(buf): int64 // nr=164; buf = 64-Byte-Puffer
Hinweis zuSysIofsReadLpid/SysIofsWriteLpid: Der Kernel übersetztuser_bufviaVmmPhysFromUserVirtin eine physische Adresse. Der übergebene Puffer muss daher eine viammapallozierte Page sein (kein Stack-Puffer).
Shell-Tool: iofs
| Befehl | Beschreibung |
|---|---|
iofs mount <disk_id> | IOFS-Volume mounten (LIP + Bitmap in RAM laden) |
iofs unmount | Checkpoint falls dirty, LIP-Tabelle freigeben |
iofs info | Status, freie Pages, gemappte LPIDs, aktiver Slot, Seq, Dirty-Flag |
iofs alloc <text> | Neue Meta-Page mit Text-Payload allozieren, LPID ausgeben |
iofs read <lpid> | Page-Header + Payload (bis 256 Zeichen) anzeigen |
iofs write <lpid> <text> | Payload überschreiben (neue physische Page, LIP aktualisiert) |
iofs free <lpid> | Physische Page freigeben + LIP-Eintrag löschen (LPID ≥ 2) |
iofs checkpoint | LIP + Bitmap in inaktiven Slot flushen |
iofs lip <lpid> | Physischen page_idx für LPID anzeigen |
Beispiel
> mkfs_iofs 1
mkfs_iofs: formatting disk 1 as IOFS... OK
> iofs mount 1
iofs: mounting disk_id=1 ... OK
> iofs alloc "Hallo IOFS"
iofs: allocated lpid=2
> iofs read 2
magic LYX! OK
lpid 2
type 1
flags 0
psize 10 bytes
payload Hallo IOFS
> iofs checkpoint
iofs: checkpoint ... OK
> iofs info
mounted yes active slot A seq=2
free pages 16057 / 16058
mapped LPIDs 2
14. WP04: Write-Ahead-Log (kernel/iofs_wal.lyx)
WP04 ergänzt einen persistenten WAL-Ring für alle Mutationen an LIP-Tabelle und Bitmap. Damit sind Änderungen nach einem Checkpoint auch bei Absturz vor dem nächsten Checkpoint wiederherstellbar — ohne den vollständigen Dual-Slot-Flip abzuwarten.
Konstanten
pub con IOFS_WAL_TYPE_LIP_UPDATE: int64 := 1; // key=lpid, value=new_page_idx
pub con IOFS_WAL_TYPE_BITMAP_SET: int64 := 2; // key=page_idx, value=0
pub con IOFS_WAL_TYPE_BITMAP_CLEAR: int64 := 3; // key=page_idx, value=0
pub con IOFS_WAL_ENTRY_SZ: int64 := 32; // Bytes je Eintrag
pub con IOFS_WAL_EPP: int64 := 128; // Einträge je 4096-Byte-Page
pub con IOFS_WAL_TOTAL: int64 := 8192; // 64 Pages × 128 Einträge (zirkulär)
WAL-Eintragsformat (32 Bytes)
Offset Größe Feld Beschreibung
────── ───── ────── ──────────────────────────────────────────────────────────
0x00 1 type 0=leer, 1=LIP_UPDATE, 2=BITMAP_SET, 3=BITMAP_CLEAR
0x01 7 (pad) Muss 0 sein
0x08 8 key LPID (LIP_UPDATE) oder page_idx (Bitmap-Ops)
0x10 8 value Neuer page_idx (LIP_UPDATE) oder 0 (Bitmap-Ops)
0x18 4 seq Monotone Sequenznummer (uint32 LE, ≥ 1)
0x1C 4 crc32c CRC32C über Bytes 0x00–0x1B (28 Bytes)
Stop-Heuristik beim Replay: type == 0 oder CRC-Fehler = Ende der geschriebenen Einträge.
Kernel-API (kernel/iofs_wal.lyx)
| Signatur | Beschreibung |
|---|---|
WalInit(initial_seq): void | Setzt g_wal_head = 0 und g_wal_seq = initial_seq. Aufgerufen von IofsMountDisk nach dem Laden des Checkpoint-Slots. |
WalAppend(type_, key, value): void | Schreibt einen 32-Byte-Eintrag in den Ring, erhöht g_wal_seq, rückt g_wal_head zirkulär vor. Aufruf-Reihenfolge: nach dem Page-Write, vor der RAM-Mutation. |
WalReplay(disk_id, from_seq, lip_arr, bmp): int64 | Scannt alle WAL-Pages linear (0 → 8191). Wendet Einträge mit seq ≥ from_seq und gültigem CRC auf lip_arr (uint16-LIP) und bmp (Bitmap-Puffer) an. Aktualisiert g_wal_head und g_wal_seq auf den Stand nach dem letzten angewendeten Eintrag. Gibt Anzahl angewendeter Einträge zurück. |
WalZero(disk_id): void | Nullt alle 64 WAL-Pages auf Disk. Aufgerufen von IofsCheckpoint nach erfolgreichem Dual-Slot-Flip. |
WalSeq(): int64 | Nächste zu vergebende Sequenznummer (gelesen von IofsCheckpoint und in den Slot-Header geschrieben). |
WalHead(): int64 | Aktueller Schreib-Index (0–8191). |
Aufruf-Sequenz in IofsWriteLpid
1. IofsAllocPage() → new_pidx
2. IofsWritePage(disk_id, new_pidx, buf) ← physische Page auf Disk
3. WalAppend(BITMAP_SET, new_pidx, 0) ← WAL: neuen Block als belegt markieren
4. WalAppend(LIP_UPDATE, lpid, new_pidx) ← WAL: LIP-Eintrag aktualisieren
5. [falls alter Block vorhanden]
WalAppend(BITMAP_CLEAR, old_pidx, 0) ← WAL: alten Block als frei markieren
6. LIP[lpid] := new_pidx ← jetzt RAM-Mutation
7. Bitmap[new] := belegt
8. Bitmap[old] := frei
Das WAL-Eintrag kommt vor der RAM-Mutation: bei Absturz nach Schritt 2 aber vor Schritt 6 rekonstruiert WalReplay beim nächsten Mount den korrekten Zustand.
Checkpoint-Lifecycle (WP04-Erweiterung)
IofsCheckpoint():
1. Bitmap → inaktiver Slot +1
2. 128 LIP-Pages → inaktiver Slot +2..+129
3. wal_s := WalSeq()
4. Slot-Header mit valid=1, seq+1, wal_seq=wal_s → inaktiver Slot +0 ← zuletzt
5. WalZero(disk_id) ← WAL-Pages leeren
6. WalInit(wal_s) ← head=0, seq=wal_s
IofsMountDisk():
1. Aktiven Slot bestimmen (valid=1, höchste seq)
2. Bitmap + LIP laden
3. wal_seq_at_checkpoint := Slot-Header +24 (uint32 LE)
4. WalInit(wal_seq_at_checkpoint)
5. WalReplay(disk_id, wal_seq_at_checkpoint, lip, bmp)
Die WAL ist ein zirkulärer Ring mit 8192 Slots. Bei sehr hoher Write-Last ohne zwischenzeitlichen Checkpoint kann der Ring überlaufen — älteste Einträge werden überschrieben. Deshalb sollteIofsCheckpointregelmäßig aufgerufen werden.
15. WP05: Graph / Edges (kernel/iofs_graph.lyx)
WP05 fügt eine gerichtete Kanten-Schicht auf IOFS-Pages auf. Jede Node-Page kann über ihr cont_lpid-Feld (Offset 0x18) auf eine verkettete Liste von Edge-List-Pages zeigen.
Kanten-Struktur
Node-Page (beliebiger Typ mit LYX!-Magic):
+0x18 edge_list_lpid (int64) — 0 = keine Kanten; >0 = LPID der ersten Edge-List-Page
Edge-List-Page (type = IOFS_TYPE_EDGE_LIST = 4):
+0x08 lpid (int64) — LPID dieser Edge-List-Page
+0x10 payload_size (uint16) — edge_count × IOFS_EDGE_SIZE
+0x12 edge_count (uint16) — Anzahl Einträge auf dieser Page
+0x18 next_edge_page (int64) — LPID der nächsten Page (0 = letzte)
+0x40 Edge-Einträge — 12 Bytes je Eintrag:
0-7 to_lpid (int64 LE)
8-9 edge_type (uint16 LE)
10-11 padding (0x0000)
con IOFS_EDGE_SIZE: int64 := 12;
con IOFS_EDGE_MAX_PER_PAGE: int64 := 336; // (4096 - 64) / 12
Wenn eine Edge-List-Page voll ist (336 Einträge), wird transparent eine neue alloziert und via next_edge_page verkettet.
Kernel-API (kernel/iofs_graph.lyx)
| Signatur | Beschreibung |
|---|---|
IofsEdgeAdd(from, to, edge_type): bool | Kante hinzufügen. Erstellt Edge-List-Page für from wenn noch keine vorhanden. Kettet neue Page an wenn aktuelle voll (> 336 Einträge). |
IofsEdgeRemove(from, to): bool | Erste Kante from→to (beliebiger edge_type) entfernen. Kompaktiert Einträge in-place (Left-Shift nach dem gelöschten Slot, letzter Slot wird genullt). |
IofsEdgeCount(from): int64 | Summe aller Kanten von from über die gesamte Page-Kette. |
IofsEdgeGetAll(from, out_buf, max): int64 | Bis zu max Kanten in out_buf kopieren (16 Bytes/Eintrag: [0-7]=to_lpid, [8-15]=edge_type). Gibt Anzahl geschriebener Einträge zurück. |
IofsEdgeHas(from, to): bool | Prüft ob Kante from→to existiert (beliebiger edge_type). |
Syscall-Binding (165–169)
| Nr | Name | Argumente | Rückgabe | Beschreibung |
|---|---|---|---|---|
| 165 | sys_iofs_edge_add | from_lpid, to_lpid, edge_type | 0 oder -1 | Gerichtete Kante hinzufügen (WP05) |
| 166 | sys_iofs_edge_rm | from_lpid, to_lpid | 0 oder -1 | Erste Kante from→to entfernen (WP05) |
| 167 | sys_iofs_edge_count | from_lpid | Anzahl oder 0 | Kanten von from_lpid zählen (WP05) |
| 168 | sys_iofs_edge_get_all | from_lpid, out_buf_uva, max_edges | Anzahl oder 0 | Kanten in Puffer lesen, 16 Bytes/Eintrag (WP05) |
| 169 | sys_iofs_edge_has | from_lpid, to_lpid | 1 oder 0 | Kanten-Existenz prüfen (WP05) |
Ring-3-Wrapper (bsys.lyx / bsys_vega.lyx)
SysIofsEdgeAdd(from_lpid, to_lpid, edge_type): int64 // nr=165
SysIofsEdgeRemove(from_lpid, to_lpid): int64 // nr=166
SysIofsEdgeCount(from_lpid): int64 // nr=167
SysIofsEdgeGetAll(from_lpid, out_buf, max): int64 // nr=168
SysIofsEdgeHas(from_lpid, to_lpid): int64 // nr=169
Shell-Befehle (iofs)
| Befehl | Beschreibung |
|---|---|
iofs edge-add <from> <to> <type> | Gerichtete Kante mit edge_type hinzufügen |
iofs edge-rm <from> <to> | Erste Kante from→to entfernen |
iofs edge-count <lpid> | Anzahl ausgehender Kanten ausgeben |
iofs edge-list <lpid> | Alle ausgehenden Kanten mit to_lpid und edge_type auflisten |
iofs edge-has <from> <to> | Kanten-Existenz prüfen (1/0) |
Beispiel
> iofs mount 1
iofs: mounting disk_id=1 ... OK
> iofs alloc "NodeA"
iofs: allocated lpid=2
> iofs alloc "NodeB"
iofs: allocated lpid=3
> iofs alloc "NodeC"
iofs: allocated lpid=4
> iofs edge-add 2 3 1
iofs: edge 2 -> 3 type=1 added
> iofs edge-add 2 4 2
iofs: edge 2 -> 4 type=2 added
> iofs edge-add 2 3 3
iofs: edge 2 -> 3 type=3 added
> iofs edge-count 2
iofs: lpid=2 edges=3
> iofs edge-has 2 3
iofs: edge 2 -> 3 exists=1
> iofs edge-rm 2 3
iofs: edge 2 -> 3 removed
> iofs edge-list 2
[0] 2 -> 4 type=2
[1] 2 -> 3 type=3
16. WP06: Graph-Traversal (kernel/iofs_traverse.lyx)
WP06 implementiert vier Graph-Traversal-Algorithmen auf den IOFS-Kanten (WP05). Alle Funktionen sind iterativ (keine Rekursion) und arbeiten mit pre-allozieren Puffern fixer Größe.
Interne Konstanten
con IOFS_VISITED_BYTES: int64 := 8192; // ceil(65536 / 8) — 1 Bit pro LPID
con TRAV_QUEUE_MAX: int64 := 4096; // max. Einträge im BFS-Queue / DFS-Stack
con SP_PARENT_BYTES: int64 := 131072; // 65536 × 2 Bytes — uint16-Parent-Array (ShortestPath)
con SP_SENTINEL: int64 := 65535; // Markiert den BFS-Startknoten im Parent-Array
Kernel-API (kernel/iofs_traverse.lyx)
| Signatur | Beschreibung |
|---|---|
IofsBfs(start_lpid, out_buf, max_nodes): int64 | BFS-Traversal ab start_lpid. Schreibt besuchte LPIDs in BFS-Reihenfolge als int64-Array in out_buf. Gibt Anzahl zurück; capped auf min(max_nodes, TRAV_QUEUE_MAX). |
IofsDfs(start_lpid, out_buf, max_nodes): int64 | DFS-Traversal (iterativer Stack). Nachbarn werden in umgekehrter Kanten-Reihenfolge gepusht, damit die erste Kante zuerst traversiert wird (LIFO-Verhalten). |
IofsReachable(from_lpid, to_lpid): bool | BFS mit Early-Exit: true sobald to_lpid im Queue gefunden wird. Gibt sofort true zurück wenn from_lpid == to_lpid. |
IofsShortestPath(from_lpid, to_lpid, path_buf, max_len): int64 | Kürzester Pfad via BFS + Parent-Array (131 072 Bytes, uint16 LE). Rekonstruiert Pfad rückwärts und dreht ihn um. Gibt Pfadlänge zurück; 0 = nicht erreichbar oder Pfad > max_len. |
Speichermodell
Jede Traversal-Funktion alloziert ihre Arbeitspuffer per mmap und gibt sie nach Abschluss frei:
BFS / DFS:
visited — 8 192 Bytes (1 Bit / LPID, 65 536 LPIDs)
queue / stack — max. TRAV_QUEUE_MAX × 8 Bytes = 32 KB
ShortestPath:
parent — 131 072 Bytes (65 536 × uint16, 0=unbesucht, 65535=Startknoten)
queue — 32 KB
Kein globaler Traversal-Zustand — jeder Aufruf ist vollständig re-entrant.
Syscall-Binding (170–173)
| Nr | Name | Argumente | Rückgabe | Beschreibung |
|---|---|---|---|---|
| 170 | sys_iofs_bfs | start_lpid, out_buf_uva, max_nodes | Anzahl oder 0 | BFS-Traversal; out_buf = int64-Array (WP06) |
| 171 | sys_iofs_dfs | start_lpid, out_buf_uva, max_nodes | Anzahl oder 0 | DFS-Traversal (iterativer Stack, WP06) |
| 172 | sys_iofs_reachable | from_lpid, to_lpid | 1 oder 0 | Erreichbarkeit prüfen (WP06) |
| 173 | sys_iofs_shortest_path | from_lpid, to_lpid, path_buf_uva, max_len | Pfadlänge oder 0 | Kürzester Pfad (WP06) |
Ring-3-Wrapper (bsys.lyx)
SysIofsBfs(start_lpid, out_buf, max_nodes): int64 // nr=170
SysIofsDfs(start_lpid, out_buf, max_nodes): int64 // nr=171
SysIofsReachable(from_lpid, to_lpid): int64 // nr=172
SysIofsShortestPath(from_lpid, to_lpid, path_buf, max_len): int64 // nr=173
Shell-Befehle (iofs)
| Befehl | Beschreibung |
|---|---|
iofs bfs <lpid> [max] | BFS-Traversal ab lpid; Standard-max=64 |
iofs dfs <lpid> [max] | DFS-Traversal ab lpid |
iofs reachable <from> <to> | Erreichbarkeit prüfen (YES/NO) |
iofs path <from> <to> [max] | Kürzesten Pfad ausgeben |
Beispiel
> iofs mount 1
iofs: mounting disk_id=1 ... OK
> iofs bfs 1
iofs bfs lpid=1 visited=4:
1
3
4
5
> iofs reachable 1 5
iofs: 1 -> 5 reachable=YES
> iofs path 1 5
iofs path (3 hops):
1 -> 3 -> 5
17. WP07: Named Nodes (kernel/iofs_names.lyx)
WP07 ergänzt einen String-zu-LPID-Namensraum auf der reservierten LPID=2. Namen sind bis zu 55 Bytes lang; pro Name-Store-Page passen 63 Einträge.
Konstanten
pub con IOFS_NS_LPID: int64 := 2; // well-known LPID für den Name Store
pub con IOFS_NS_ENTRY_SIZE: int64 := 64;
pub con IOFS_NS_MAX_NAME: int64 := 55;
pub con IOFS_NS_ENTRIES_PER_PAGE: int64 := 63; // (4096 − 64) / 64
pub con IOFS_NS_OUT_ENTRY: int64 := 80;
LPID-Reservierung: NachIofsNameInit()sind LPID 1 (Root) und LPID 2 (Name Store) belegt. Neue Allokationen viaIofsAllocLpidSlot()starten ab LPID 3.
Name-Store-Page-Layout
Name-Store-Pages haben type = IOFS_TYPE_NAME_STORE (5). Das cont_lpid-Feld (Offset 0x18) zeigt auf die nächste Name-Store-Page in der Kette (0 = letzte Page).
Standard LYX!-Header (0x00–0x3F):
0x04 IOFS_TYPE_NAME_STORE (5)
0x08 LPID dieser Page
0x12–0x13 entry_count (uint16 LE)
0x18 next_name_page_lpid (int64, 0 = letzte Page)
Payload ab 0x40: entry_count × 64 Bytes je Eintrag:
+0 lpid (int64 LE) — gebundener LPID
+8 name_len (uint8) — Namenslänge in Bytes (1–55)
+9 name (bis 55 Bytes, kein Null-Terminator gespeichert)
Kernel-API (kernel/iofs_names.lyx)
| Signatur | Beschreibung |
|---|---|
IofsNameInit(): bool | Stellt sicher dass LPID=2 als Name-Store-Root existiert. Idempotent — sicher nach jedem Mount aufzurufen; prüft via IofsLipGet(2) != 0. |
IofsNameBind(name, name_len, lpid): bool | Bindet Name an LPID. Existiert der Name bereits, wird nur der LPID aktualisiert (2-Pass: Pass 1 sucht zum Updaten, Pass 2 findet freien Slot oder kettet neue Page an). |
IofsNameLookup(name, name_len): int64 | Sucht Name linear in der Page-Kette. Gibt gebundenen LPID zurück; 0 = nicht gefunden. |
IofsNameUnbind(name, name_len): bool | Entfernt Eintrag. Kompaktiert verbleibende Einträge der Page in-place (Left-Shift, letzter Slot wird genullt). Gibt false wenn Name nicht gefunden. |
IofsNameList(out_buf, max_entries): int64 | Kopiert bis zu max_entries Einträge in out_buf (80 Bytes/Eintrag, siehe unten). Gibt Anzahl kopierter Einträge zurück. |
IofsNameList-Ausgabepuffer (80 Bytes/Eintrag)
+0 lpid (int64) — gebundener LPID
+8 name_len (int64) — Namenslänge (uint8, zero-extended)
+16 name (bis 56 Bytes inkl. Null-Terminator)
Syscall-Binding (174–178)
| Nr | Name | Argumente | Rückgabe | Beschreibung |
|---|---|---|---|---|
| 174 | sys_iofs_name_init | — | 0 oder -1 | Name-Store initialisieren (idempotent, WP07) |
| 175 | sys_iofs_name_lookup | name_uva, name_len | LPID oder 0 | Name → LPID (0 = nicht gefunden, WP07) |
| 176 | sys_iofs_name_bind | name_uva, name_len, lpid | 0 oder -1 | Name an LPID binden / aktualisieren (WP07) |
| 177 | sys_iofs_name_unbind | name_uva, name_len | 0 oder -1 | Bindung entfernen (WP07) |
| 178 | sys_iofs_name_list | out_buf_uva, max_entries | Anzahl oder 0 | Alle Bindungen auflisten, 80 Bytes/Eintrag (WP07) |
Ring-3-Wrapper (bsys.lyx)
SysIofsNameInit(): int64 // nr=174
SysIofsNameLookup(name: pchar, name_len): int64 // nr=175; Rückgabe = LPID oder 0
SysIofsNameBind(name: pchar, name_len, lpid): int64 // nr=176
SysIofsNameUnbind(name: pchar, name_len): int64 // nr=177
SysIofsNameList(out_buf, max_entries): int64 // nr=178
Shell-Befehle (iofs)
| Befehl | Beschreibung |
|---|---|
iofs name-init | Name-Store auf LPID=2 initialisieren (idempotent) |
iofs name-bind <name> <lpid> | Name an LPID binden (Update wenn Name schon existiert) |
iofs name-lookup <name> | Gebundenen LPID ausgeben (0 = nicht gefunden) |
iofs name-unbind <name> | Bindung entfernen |
iofs name-list | Alle Bindungen ausgeben (max. 64 Einträge) |
Beispiel
> iofs mount 1
iofs: mounting disk_id=1 ... OK
> iofs name-init
iofs name-init: OK
> iofs name-bind system 1
iofs: 'system' -> lpid=1 bound
> iofs name-bind config 3
iofs: 'config' -> lpid=3 bound
> iofs name-lookup config
iofs: name='config' lpid=3
> iofs name-list
lpid=1 'system'
lpid=3 'config'
> iofs name-unbind config
iofs: 'config' unbound
18. Implementierungsstand
| Komponente | Status | Quelldatei |
|---|---|---|
| Superblock, Root-Node, Checkpoint-Slots, WAL, Bitmap | Implementiert (WP01+WP09) | kernel/iofs_alloc.lyx |
| Block-Allocator (Alloc/Free/Count) | Implementiert (WP01) | kernel/iofs_alloc.lyx |
| Page-I/O (IofsReadPage / IofsWritePage) | Implementiert | kernel/iofs_alloc.lyx |
sys_mkfs_iofs (Syscall 155) | Implementiert | kernel/ring3.lyx, kernel/vfs.lyx |
Shell-Tool mkfs_iofs | Implementiert | bin/mkfs_iofs.lyx |
| Mount / LIP-Tabelle (128 KB) | Implementiert (WP02) | kernel/iofs_rw.lyx |
| LPID-Lesen/Schreiben (sys 156–158) | Implementiert (WP02) | kernel/iofs_rw.lyx |
| NewPage / FreeLpid (sys 159–160) | Implementiert (WP02) | kernel/iofs_rw.lyx |
| Checkpoint / Unmount (sys 161–162) | Implementiert (WP02) | kernel/iofs_rw.lyx |
| LipGet / Info (sys 163–164) | Implementiert (WP02) | kernel/iofs_rw.lyx |
Shell-Tool iofs | Implementiert (WP02+WP05) | bin/iofs.lyx |
| Graph-Kanten (IofsEdgeAdd/Remove/Count/GetAll/Has) | Implementiert (WP05) | kernel/iofs_graph.lyx |
| Syscalls 165–169 (edge_add/rm/count/get_all/has) | Implementiert (WP05) | kernel/ring3.lyx |
| VFS-Mount (IOFS als aktives sys_open-Backend) | Geplant (M5) | — |
| LBF-Zero-Load-Ausführung | Geplant (M5) | — |
| Panic-Sandbox, Kompaktierung | Geplant (M6+) | — |
| CRC32C-Engine (IofsCrc32c, IofsPageSetCrc, IofsPageVerifyCrc) | Implementiert (WP03) | kernel/iofs_alloc.lyx |
| WAL-Ring (WalInit/WalAppend/WalReplay/WalZero, 8192 Einträge) | Implementiert (WP04) | kernel/iofs_wal.lyx |
| Graph-Traversal (IofsBfs/IofsDfs/IofsReachable/IofsShortestPath) | Implementiert (WP06) | kernel/iofs_traverse.lyx |
| Syscalls 170–173 (bfs/dfs/reachable/shortest_path) | Implementiert (WP06) | kernel/ring3.lyx |
| Named Nodes (IofsNameInit/Bind/Lookup/Unbind/List) | Implementiert (WP07) | kernel/iofs_names.lyx |
| Syscalls 174–178 (name_init/lookup/bind/unbind/list) | Implementiert (WP07) | kernel/ring3.lyx |
FAT32 bleibt das aktive sys_open/sys_read/sys_write-Backend. IOFS ist direkt über die Syscalls 155–164 erreichbar — als eigenständige Page-Store-Engine, noch nicht als VFS-Dateisystem.
19. Verhältnis zu VFS und FAT32
Ring-3-Anwendungen
│
├─ sys_open / sys_read / sys_write → VFS → FAT32 (aktives VFS-Backend)
│
└─ Syscalls 155–178 direkt → IOFS (Page-Store-Engine, kein VFS-Layer)
mkfs_iofs / iofs mount / iofs alloc / iofs read / iofs write / iofs checkpoint
iofs edge-* / iofs bfs / iofs dfs / iofs path / iofs name-*
IOFS ist ab WP02 als eigenständige Page-Store-Engine nutzbar. Der VFS-Mount-Layer (sys_open auf IOFS-Volumes) folgt in M5.
20. Quelldateien
| Modul | Datei |
|---|---|
| Block-Allocator, mkfs, Page-I/O | kernel/iofs_alloc.lyx |
| Mount, Read, Write, Checkpoint (WP02) | kernel/iofs_rw.lyx |
| Write-Ahead-Log / WAL-Ring (WP04) | kernel/iofs_wal.lyx |
| Graph-Kanten (WP05) | kernel/iofs_graph.lyx |
| Graph-Traversal, Kürzeste Pfade (WP06) | kernel/iofs_traverse.lyx |
| Named Nodes, Name-Store (WP07) | kernel/iofs_names.lyx |
| VFS-Wrapper (VfsMkfsIofs, VfsIofsMountDisk …) | kernel/vfs.lyx |
| Syscall-Handler (nr=155–178) | kernel/ring3.lyx |
| Ring-3-Wrapper | bin/bsys.lyx, vega/bsys_vega.lyx |
| Shell-Tool mkfs_iofs | bin/mkfs_iofs.lyx |
| Shell-Tool iofs | bin/iofs.lyx |
Letzte Aktualisierung: 2026-06-20
