Inhaltsverzeichnis

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 tragen LYX! an Byte 0. Unterscheidung erfolgt über Byte 0x0004: LBF-Genesis hat dort die format_version (0x01 = v1.0, 0x02 = v1.1); IOFS-Pages haben dort IOFS_TYPE_META (1) bis IOFS_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:

  1. LBF-Blöcke werden als IOFS-Pages gespeichert (Typ 0x04 für Genesis, 0x02 für Code-/Daten-Pages)
  2. Der HUMAN_INTENT-Text (TLV 0x01 aus dem Genesis-Block) wird durch das KI-Subsystem in einen Embedding-Vektor umgewandelt
  3. Der Embedding-Vektor wird an die Genesis-Page annotiert (sys_sem_annotate)
  4. Die Page wird im Kernel-Wissensgraph registriert (sys_graph_node_create)
  5. 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).

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ätzlich wal_seq_at_checkpoint bei Offset +24 (uint32 LE). IofsCheckpoint schreibt dort den aktuellen WalSeq()-Wert, bevor der Header auf Disk kommt. IofsMountDisk liest diesen Wert und übergibt ihn an WalInit(), damit WalReplay weiß, 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:

  1. IofsAllocInit(disk_id) — Bitmap aufbauen
  2. Superblock (Page 0): „IOFS“-Magic + alle Layout-Konstanten
  3. Root Node (Page 1): „LYX!“-Magic, IOFS_TYPE_META, IOFS_FLAG_IMMUTABLE, LPID=1, payload=„IOFS_ROOT_v1.1“ (14 Bytes bei Offset 0x40)
  4. WAL (Pages 262–325): alle Pages genullt
  5. 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)
  6. 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 zu SysIofsReadLpid / SysIofsWriteLpid: Der Kernel übersetzt user_buf via VmmPhysFromUserVirt in eine physische Adresse. Der übergebene Puffer muss daher eine via mmap allozierte 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 sollte IofsCheckpoint regelmäß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 fromto (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 fromto 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: Nach IofsNameInit() sind LPID 1 (Root) und LPID 2 (Name Store) belegt. Neue Allokationen via IofsAllocLpidSlot() 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