Inhaltsverzeichnis

Lyx OS – Kernel-Interna

Diese Seite richtet sich an Beitragende, die den Kernel weiterentwickeln möchten: Build-Ablauf, Modul-Interaktion, Initialisierungsreihenfolge und praktische Debugging-Techniken.

Architektur · Syscall-ABI · Übersicht


1. Verzeichnisstruktur

lyx-os/
├── bootloader/
│   ├── boot.asm          ← UEFI-Bootloader (~2900 Zeilen NASM)
│   ├── build.sh          ← Build-Skript (Assemble + Compile + Image)
│   └── run.sh            ← QEMU-Startskript
├── kernel/
│   ├── kernel.lyx        ← Kernel-Einstiegspunkt; importiert alle Module
│   ├── exceptions.lyx    ← IDT (256 Gates), CPU-Fault-Routing
│   ├── pmm.lyx           ← Physical Memory Manager (Bitmap)
│   ├── vmm.lyx           ← Virtual Memory Manager (PML4, per-Prozess CR3)
│   ├── process.lyx       ← Prozessmodell, Scheduler-Bootstrap
│   ├── sync.lyx          ← Mutex, Semaphor, Spinlock
│   ├── smp.lyx           ← SMP, LAPIC, AP-Trampoline, Task-API
│   ├── ata.lyx           ← ATA-Disk-I/O (Legacy + Multi-Disk)
│   ├── disk.lyx          ← Disk-Abstraktion (Probing, Modell-String, Sektorzahl)
│   ├── mbr.lyx           ← MBR-Partition-Tabelle (Lesen/Schreiben)
│   ├── fat32.lyx         ← FAT32-Implementierung mit LFN-Schreiben
│   ├── vfs.lyx           ← Virtual-Filesystem-Layer
│   ├── keyboard.lyx      ← PS/2-Tastatureingabe, Layout-Umschaltung
│   ├── initrd.lyx        ← In-Memory-Ramdisk (LIXR-Format)
│   ├── locale.lyx        ← Internationalisierung (5 Locales, /config/locale.cfg)
│   ├── xhci.lyx          ← XHCI-Treiber (USB 3.x, WP25)
│   ├── iofs_alloc.lyx    ← IOFS Block-Allocator, mkfs, Page-I/O (WP01+WP09, Syscall 155)
│   ├── iofs_rw.lyx       ← IOFS Mount/Read/Write/Checkpoint (WP02, Syscalls 156–164)
│   ├── iofs_wal.lyx      ← IOFS Write-Ahead-Log (WP04, kernel-intern, kein Syscall)
│   ├── iofs_graph.lyx    ← IOFS Graph/Edges (WP05, Syscalls 165–169)
│   ├── iofs_traverse.lyx ← IOFS Graph-Traversal BFS/DFS/Reachable/ShortestPath (WP06, Syscalls 170–173)
│   ├── iofs_names.lyx    ← IOFS Named Nodes / Name-Store (WP07, Syscalls 174–178)
│   ├── ramdisk.lyx       ← RAM-Disk-Treiber (IDs 4–7, Syscalls 153–154, WP30)
│   ├── net.lyx           ← E1000-Treiber, DHCP, ARP, TCP-Stack (WP26, WP16-TCP, Syscalls 180–184)
│   └── ring3.lyx         ← ELF64-Loader, SysSpawn, Syscall-Handler, Capabilities
├── shell/
│   └── shell.lyx         ← Interaktive Ring-3-Shell
└── doku/
    ├── syscalls.md       ← Syscall-ABI-Spezifikation
    └── fahrplan.md       ← Meilenstein-Plan


2. Build-Ablauf

bash bootloader/build.sh

Das Skript führt vier Phasen aus:

  1. Bootloader assemblierennasm -f bin boot.asm -o BOOTX64.EFI
  2. Kernel kompilierenlyxc –target=lyxos für jeden .lyx-Kernel-File, dann Linken zu kernel.elf
  3. Disk-Image aufbauen — 128-MB-GPT-Image mit FAT32-EFI-Partition
  4. ESP befüllenBOOTX64.EFI nach /EFI/BOOT/, kernel.elf in die Wurzel

Einzelne Module neu kompilieren (ohne Full-Build):

lyxc --target=lyxos kernel/fat32.lyx -o kernel/fat32.lyu

Die .lyu-Dateien sind vorkompilierte Units, die beim Link-Schritt zusammengefasst werden.


3. Kernel-Einstiegspunkt

Der Bootloader springt in pub fn main(boot_info_ptr: int64) in kernel.lyx. Das Argument ist ein Zeiger auf eine BootInfo-Struktur, die der Bootloader vor dem ExitBootServices-Aufruf aufgebaut hat:

// BootInfo-Layout (boot_info_ptr ist der Zeiger)
// Offset  0: mmap_ptr      — Zeiger auf UEFI-Memory-Map
// Offset  8: mmap_size     — Größe der Memory-Map in Bytes
// Offset 16: desc_size     — Größe eines Memory-Deskriptors
// Offset 24: kernel_end    — Physische Endadresse des Kernels
// Offset 32: bump_ptr_addr — Adresse des Bump-Allocator-Zeigers
// Offset 40: r3sc_addr     — Physische Adresse des r3_sc_block (Ring-3 ↔ Kernel-Protokoll)

pub fn main(boot_info_ptr: int64): int64 {
    var mmap_ptr:      int64 := peek64(boot_info_ptr);
    var mmap_size:     int64 := peek64(boot_info_ptr + 8);
    var desc_size:     int64 := peek64(boot_info_ptr + 16);
    var kernel_end:    int64 := peek64(boot_info_ptr + 24);
    var bump_ptr_addr: int64 := peek64(boot_info_ptr + 32);
    var r3sc_addr:     int64 := peek64(boot_info_ptr + 40);
    // ...
}


4. Initialisierungsreihenfolge

Die Reihenfolge ist durch Abhängigkeiten erzwungen — sie darf nicht geändert werden ohne die Konsequenzen zu prüfen:

1. PMM          — Bitmap-Allocator für physische Pages (braucht UEFI-Memory-Map)
 2. VMM          — PML4-Page-Tables, CR3 laden (braucht PMM für Page-Allokationen)
 3. RNG-Seed     — rdtsc() → RandomSeed() (braucht VMM für mmap)
 4. SMP          — LAPIC init, AP-Trampoline, INIT+SIPI senden
 5. VFS          — fd-Tabelle anlegen; ruft intern Fat32VolumeInit + MbrInit auf
 6. DiskInit     — alle 4 ATA-Kanäle proben, Sektorzahl + Modell-String cachen
 7. FAT32-Mount  — VfsMountFat32(2048): BPB lesen, Root-Cluster bestimmen
 8. LocaleInit   — /config/locale.cfg lesen, Locale + Tastaturbelegung setzen
 9. Initrd-Mount — InitrdBuildEmpty + VfsMountInitrd → /initrd/ mounten
10. Ring-3       — SysSpawn("shell.elf"): ELF laden, per-Prozess CR3, shell ausführen
11. Keyboard     — KbdReadChar-Poll nach Shell-Exit (mit Timeout)
12. Sync-Tests   — MutexCreate/Lock/Unlock, SemCreate/Wait/Post
13. Scheduler    — ProcInit(), ProcActivate() → preemptiv (100 Hz), Endlos-Loop P0

 
Wichtig für Beitragende: Module dürfen mmap, peek64, poke64 und PrintLn erst nach VMM-Init aufrufen. Vor VfsInit() darf kein Code auf Dateien zugreifen.

5. Module: Aufgaben und Schnittstellen

PMM (pmm.lyx)

Bitmap-basierter Physical Memory Manager. 4 GB Adressraum, 4-KB-Pages.

PmmInit(mmap_ptr, mmap_size, desc_size, kernel_end);  // UEFI-Map parsen
var page: int64 := PmmAllocPage();                     // Eine Page allozieren
PmmFreePage(page);                                     // Page zurückgeben
var free: int64 := PmmFreeCount();                     // Anzahl freier Pages

Physische Adressen die von UEFI als EfiConventionalMemory markiert sind, werden als frei eingetragen. Kernel-Code und Bootloader-Bereich werden explizit reserviert.

VMM (vmm.lyx)

Verwaltet die PML4-Page-Table-Hierarchie. Alle 4 GB werden als Identity-Map (1:1 physisch ↔ virtuell) mit 2-MB-Huge-Pages eingetragen. Ab WP14 kommen per-Prozess 4-KB-Page-Tables für Ring-3 hinzu.

VmmInit();                                          // PML4 aufbauen und CR3 laden
var cr3: int64 := VmmGetCr3();                     // Aktuellen CR3 lesen

// WP14: Per-Prozess Address-Space
var proc_pml4: int64 := VmmAllocProcessPML4(
    SHELL_PHYS_BASE, elf_sz_pages,                 // ELF-Bereich
    stack_phys, USER_STACK_SIZE);                  // User-Stack
VmmMapUserPage(proc_pml4, virt_addr, phys_addr);  // Einzelne 4-KB-Seite mappen
VmmSetUserHeapVirt(USER_HEAP_BASE);                // Heap-Pointer für user_mmap setzen
var virt: int64 := VmmGetUserHeapVirt();           // Heap-Pointer lesen
var phys: int64 := VmmPhysFromUserVirt(proc_cr3, vaddr);  // Adress-Translation
var proc_cr3: int64 := VmmGetCurrentProcCr3();    // Aktiven Prozess-CR3 lesen
var page: int64 := VmmPmmAllocPage();              // Physische Page allozieren

Exceptions (exceptions.lyx)

IDT mit 256 Gates. CPU-Exceptions werden auf panic() oder Fault-Handler weitergeleitet.

ExceptionsInit();   // Wird implizit von VMM aufgerufen; kein manueller Aufruf nötig

SMP (smp.lyx)

LAPIC-Init, AP-Trampoline bei physisch 0x8000, INIT+SIPI-Sequenz.

var ncpu: int64 := GetCpuCount();        // CPUID → Anzahl logischer CPUs
var ap_stack: int64 := mmap(0, 8192, 3, 34, -1, 0);
SmpPrepareTrampoline(ap_stack + 8192);   // Trampoline schreiben
SmpStartAp(1);                           // SIPI an LAPIC-ID 1
var ready: int64 := GetApStartedCount(); // Wieviele APs sind hochgefahren?

Sync (sync.lyx)

Kernel-seitige Synchronisationsprimitive für Ring-0-Code.

var mx: int64 := MutexCreate(MUTEX_PLAIN);
MutexLock(mx);
// kritischer Abschnitt
MutexUnlock(mx);

var sem: int64 := SemCreate(1, 0);
SemWait(sem);
SemPost(sem);

var sl: int64 := GetPrintSpinlockAddr();
SpinlockAcquire(sl);
SpinlockRelease(sl);

ATA (ata.lyx)

PIO-Mode-Disk-I/O. Sektorweises Lesen und Schreiben (512 Bytes/Sektor). Kein DMA.

// Legacy (Primary Master, disk_id implizit 0):
AtaReadSector(lba, dst_buf);           // → vmm_op26
AtaWriteSector(lba, src_buf);          // → vmm_op27

// Multi-Disk (disk_id: 0=pri-master 1=pri-slave 2=sec-master 3=sec-slave):
var sects: int64 := AtaProbe(disk_id, identify_buf);  // IDENTIFY; -1 = nicht vorhanden
AtaReadDisk(disk_id, lba, dst_buf);   // → vmm_op43; 0 = OK, -1 = Fehler
AtaWriteDisk(disk_id, lba, src_buf);  // → vmm_op44; inkl. FLUSH CACHE

Disk (disk.lyx)

Abstraktionsschicht über ATA. Probt beim Start alle 4 ATA-Kanäle und cacht Sektorzahl + Modell-String (byteswapped aus IDENTIFY-Daten extrahiert).

DiskInit();                                     // alle 4 Kanäle proben + cachen
var ok: bool := DiskPresent(disk_id);          // Disk vorhanden?
var n: int64 := DiskSectorCount(disk_id);      // Sektorzahl (= Kapazität / 512 B)
DiskPrintInfo();                               // Auflistung auf COM1/FB

MBR (mbr.lyx)

Liest und schreibt MBR-Partitions-Einträge (klassische 4-Einträge-Tabelle, Typ 0x0C = FAT32 LBA). Wird von VfsMkPart und VfsMountDisk genutzt.

MbrInit();                                              // 512-B-Buffer anlegen (von VfsInit aufgerufen)
MbrWritePart(disk_id, part_idx, lba_start, sectors);   // Eintrag schreiben (0–3)
var out: int64 := mmap(0, 16, 3, 34, -1, 0);
MbrReadPart(disk_id, part_idx, out);                    // lba_start@out+0, sectors@out+8

FAT32 (fat32.lyx)

Vollständige FAT32-Implementierung. Cluster-Ketten, BPB-Parsing, Verzeichnis-Einträge (inkl. LFN-Unterstützung).

var root_cluster: int64 := Fat32GetRootCluster();
var n: int64 := Fat32ListDir(root_cluster);   // Root-Verzeichnis auflisten

VFS (vfs.lyx)

Abstraktionsschicht über FAT32 und Initrd. Exportiert ein posix-artiges open/read/write/close-Interface für Kernel-Code und Ring-3-Syscall-Handler. MAX_FD = 32 gleichzeitig offene Deskriptoren.

VfsInit();                                               // von MbrInit + Fat32VolumeInit aufgerufen
VfsMountFat32(2048);                                     // Partition ab LBA 2048 mounten
VfsMountInitrd(base, size);                              // Ramdisk unter /initrd/ mounten
VfsMountDisk(vol_id, disk_id, lba_start);                // Volume mounten (Multi-Volume)
VfsSwitchVolume(vol_id);                                 // Aktives Volume wechseln, CWD → "/"

var fd: int64 := VfsOpen(AT_CWD, "datei.txt", O_READ);
var n:  int64 := VfsRead(fd, buf, 4096);
VfsWrite(fd, buf, n);
VfsSeek(fd, offset, SEEK_SET);                          // SEEK_SET=0, SEEK_CUR=1, SEEK_END=2
var fd2: int64 := VfsDup(fd, 0);                        // fd duplizieren
VfsClose(fd);

VfsStat(AT_CWD, "test.txt", statbuf);                  // size@statbuf+0, type@statbuf+8
VfsFstat(fd, statbuf);
var t: int64 := VfsFdType(fd);                         // FD_FILE=1, FD_KBD=2, FD_DIR=3, FD_INITRD=4
VfsSync(fd);                                            // Stub (FAT32 schreibt per Commit)

VfsMkdir(AT_CWD, "mydir");
var dfd: int64 := VfsOpenDir(AT_CWD, ".");
VfsReadDir(dfd, dbuf, 20);                             // 48-B-DirEntry-Structs (name[32]+size[8]+type[8])
VfsRename(AT_CWD, "old.txt", AT_CWD, "new.txt");
VfsUnlink(AT_CWD, "old.txt", 0);                       // UNLINK_DIR=1 für Verzeichnisse

VfsGetCwd(buf, size);
VfsChdir(AT_CWD, "subdir");
var kbdfd: int64 := VfsOpenKbd();                      // Keyboard-fd für IRQ-Binding
VfsIrqBind(1, kbdfd);                                  // IRQ 1 (PS/2 Kbd) an fd binden

VfsDiskPrintInfo();                                    // Disk-Übersicht auf COM1/FB
VfsMkPart(disk_id, lba_start, sectors);               // MBR-Partition anlegen
VfsMkFat32(disk_id, lba_start, sectors);              // FAT32 formatieren
VfsMkFat32ByPart(disk_id, part_no);                   // FAT32 per Partitionsnummer
VfsMountByPart(vol_id, disk_id, part_no);             // Mount per Partitionsnummer
VfsGptMount(disk_id, vol_id_start);                   // GPT scannen + alle FAT-Partitionen mounten
VfsDiskMap(disk_id);                                  // Partition-Layout mit Lücken (vmm_op41)

→ Shell-Befehle, die diese Funktionen nutzen: diskinfo · partinfo · part · mkfat32 · mount · mountp · vol · gpt

FD-Slot-Layout (48 Bytes pro Eintrag in fd_table):

Offset Feld Bedeutung
0 type FD_EMPTY=0, FD_FILE=1, FD_KBD=2, FD_DIR=3, FD_INITRD=4
8 cluster Aktueller FAT32-Cluster (oder 0 für Initrd)
16 offset Byte-Offset innerhalb der Datei
24 size Dateigröße in Bytes
32 flags FD_FLAG_CLOEXEC=1, FD_FLAG_APPEND=2
40 dir_cluster Start-Cluster des enthaltenden Verzeichnisses

Initrd (initrd.lyx)

In-Memory-Ramdisk. Format: LIXR-Magic (4 Bytes) gefolgt von Einträgen (Name + Daten) und einem 4-Byte-Null-Terminator.

var base: int64 := InitrdBuildEmpty();             // Minimales 4-KB-Initrd mit Magic + Terminator
VfsMountInitrd(base, size);                        // Mountet unter /initrd/
InitrdFind("dateiname", size_out);                 // → physische Datenadresse oder -1
InitrdRead("dateiname", buf, offset, count);       // Bytes lesen
InitrdEntryCount();                                // Anzahl Einträge

Initrd-Eintrag-Layout:

[4B name_len uint32 LE, inkl. Null-Terminator]
[name_len Bytes Name (inkl. '\0')]
[8B data_len uint64]
[data_len Bytes Daten]

Locale (locale.lyx)

Internationalisierung: 5 Locales, Zahlenformat (Tausender-Trennzeichen), Zeitformat (24h oder 12h AM/PM) und Datumsformat (MDY, DMY-Dot, DMY-Slash). Liest /config/locale.cfg beim Start.

LocaleInit();                          // /config/locale.cfg lesen + KbdSetLayout aufrufen
LocaleFormatInt(1234567, buf);         // "1,234,567" (EN) oder "1.234.567" (DE)
LocaleFormatTime(14, 5, buf);          // "14:05" (24h) oder "2:05 PM" (12h)
LocaleFormatDate(12, 6, 2026, buf);   // je nach Locale: "06/12/2026" / "12.06.2026" / "12/06/2026"
LocaleSummary(buf);                    // Zusammenfassung als ASCII-String
LocalePrintBuf(buf);                   // Ausgabe auf COM1/FB (char-by-char)

Konstante Wert Locale
LOC_EN_US 0 Englisch US (MDY, Komma-Tausender, 12h)
LOC_DE_DE 1 Deutsch (DMY-Punkt, Punkt-Tausender, 24h)
LOC_FR_FR 2 Französisch (DMY-Slash, Space-Tausender, 24h)
LOC_EN_GB 3 Englisch GB (DMY-Slash, Komma-Tausender, 24h)
LOC_ES_ES 4 Spanisch (DMY-Slash, Punkt-Tausender, 24h)

Ring-3 (ring3.lyx)

ELF64-Loader, Syscall-Handler und Capability Routing Gate. SysSpawn lädt ein ELF-Binary aus dem VFS, legt per-Prozess-Page-Tables an und startet Ring-3. Der Kernel kommuniziert mit Ring-3 über den r3_sc_block (physisch adressierter Shared-Memory-Block).

// SysSpawn: ELF laden und als Ring-3-Prozess starten
var exit_code: int64 := SysSpawn("shell.elf", r3sc_addr);

// Capabilities einschränken (Aufruf aus Ring-3 via Syscall 87):
SysPledge(PLEDGE_STDIO | PLEDGE_VFS);  // irreversibel; kein PLEDGE_EXEC mehr → sys_spawn verboten

WP17b: Fenstersystem, Ereignisse und Mauseingabe

ring3.lyx implementiert ab WP17b drei weitere Kernel-Subsysteme: Fenstertabelle, Ereignis-Ring und Mauseingabe.

Fenstertabelle (win_table)

Max. 32 Fenster × 104 Bytes/Slot. Lazy-Allokiert beim ersten sys_win_create-Aufruf aus dem PMM-Bump-Allocator (3 328 Bytes).

Offset Feld Bedeutung
0 win_id Monoton steigende ID; 0 = freier Slot
8 owner_pid PID des erzeugenden Prozesses
16 x Linke Kante (Pixel)
24 y Obere Kante (Pixel)
32 w Breite (Pixel)
40 h Höhe (Pixel)
48 z_order Z-Ordnung (höher = weiter vorne)
56 shm_id (reserviert)
64 flags Fenster-Flags (derzeit immer 0)
72 state 0 = frei, 1 = aktiv
80 shm_phys Physische Basisadresse des Fenster-Framebuffers
88 next_z Scratch für Z-Order-Berechnung

Framebuffer-Format: 32-bit XRGB, zeilenweise, stride = w × 4 Bytes. sys_win_get_fb (nr=115) mappt die physischen Seiten in den User-Adressraum des aufrufenden Prozesses.

Ereignis-Ring (ev_table)

Pro-PID-Ringpuffer für asynchrone Ereignisse (Maus, Tastatur, Fensterereignisse). Max. 8 PIDs × 16 Slots × 32 Bytes = 4 096 Bytes.

Offset Feld Beschreibung
0 type Ereignistyp
8 a Parameter A
16 b Parameter B
24 c Parameter C (beim Senden via sys_event_send derzeit immer 0)

Interne Syscall-Nummern (WP17b)

Diese Nummern beziehen sich auf das r3_sc_block-Protokoll (nr-Feld). Sie sind nicht identisch mit den öffentlichen Hex-Nummern aus Syscall-ABI.

Nr Name Argumente (a0, a1, a2, a3) Rückgabe
110 sys_win_create x, y, w, h win_id oder −1
111 sys_win_destroy win_id 0 / −1
112 sys_win_raise win_id 0 / −1; setzt z_order auf max+1
113 sys_win_move win_id, x, y 0 / −1
114 sys_win_resize win_id, new_w, new_h 0 / −1; nur Metadaten, kein FB-Realloc
115 sys_win_get_fb win_id user_virt des FB oder −1
121 sys_event_send pid, type, a, b 0
122 sys_event_recv out_buf_uva 0 (Ereignis vorhanden) / −1 (Ring leer)
126 sys_get_mouse_x Maus-X-Koordinate
127 sys_get_mouse_y Maus-Y-Koordinate
128 sys_get_mouse_btn Maustasten-Bitmask
129 sys_set_mouse_bounds max_x, max_y 0; einmalig vom Compositor nach DisplayInit aufgerufen
130 sys_win_get_table_phys Physische Adresse der win_table (Compositor-Direktzugriff)
131 sys_kbd_poll Zeichen oder 0 (non-blocking, kehrt sofort zurück)
148 sys_win_set_title win_id, title_ptr 0 / −1; Fenster-Titel setzen (WP27)
149 sys_win_find_by_idx idx win_id oder −1 (WP27)
150 sys_win_get_title win_id, buf 0 / −1; Titel in buf lesen (WP27)
151 sys_win_get_geom win_id, out_buf 0 / −1; out_buf = {x,y,w,h} je int64 (WP29)
152 sys_win_get_pid win_id owner_pid oder −1 (WP29)

Hinweise:

→ Vollständige Beschreibung: Prozesse & Ring-3


6. Neues Kernel-Modul hinzufügen

  1. Neue Datei kernel/meinmodul.lyx anlegen
  2. import meinmodul; am Anfang von kernel.lyx eintragen
  3. Initialisierungsfunktion (z.B. MeinModulInit()) an der richtigen Stelle in kernel.lyx aufrufen
  4. Im Build-Skript build.sh den Compile-Schritt für das neue Modul ergänzen:

lyxc --target=lyxos kernel/meinmodul.lyx -o kernel/meinmodul.lyu

Konventionen für Kernel-Module:


7. Debugging-Techniken

Serielle Ausgabe

PrintLn, PrintStr und PrintInt schreiben sowohl auf COM1 (serielle Konsole) als auch auf den QEMU-Debug-Port (0xE9 / debugcon). Beides erscheint im Terminal wenn run.sh mit –headless gestartet wird.

bash bootloader/run.sh --headless 2>&1 | tee kernel_log.txt

Debug-Konsole

tail -f /tmp/lyx_debugcon.txt

QEMU-Monitor

Im laufenden QEMU Ctrl-Alt-2 drücken:

info registers       # CPU-Registerstand aller VCPUs
info mem             # Page-Table-Dump
x/10i $rip           # Disassembly ab aktuellem Instruction Pointer
xp /10gx 0x200000    # Physischer Speicher-Dump ab Kernel-Basis

Kernel-Panic und assert

// In Kernel-Code:
assert(condition, "Fehlermeldung");   // Hält die Maschine an wenn condition false
panic("Unbekannter Zustand");         // Sofortiger Halt mit Debug-Ausgabe

Beim Panic wird der Registerstand auf COM1 ausgegeben, bevor die CPU in eine Endlosschleife geht (hlt-Loop). QEMU-Monitor zeigt dann den letzten Stand.

GDB über QEMU

# run.sh mit GDB-Server starten
bash bootloader/run.sh --gdb     # wartet auf Port 1234

# In zweitem Terminal:
gdb kernel/kernel.elf
(gdb) target remote :1234
(gdb) break PmmAllocPage
(gdb) continue


8. Prozessmodell

Kernel-Threads (Ring-0):

SMP-Tasks (leichtgewichtig, Ring-0):

Ring-3-Prozesse (Userspace):

→ Details: Prozesse & Ring-3 · SMP & Tasks


9. Meilenstein-Übersicht

Meilenstein Inhalt Status
M1 — Boot & Bare-Metal UEFI-Bootloader, ELF-Loader
M2 — Kernel-Kern PMM, VMM, IDT, SMP
M3 — Runtime & Scheduler Laufzeit, Mutex, Semaphor, Prozessmodell
M4 — I/O ATA, FAT32 (inkl. LFN-Write), VFS, Keyboard
M5 — Ring-3 & Shell WP12–WP15 ✅; WP17b ✅; IOFS WP01–WP07+GC ✅; RAM-Disk WP30 ✅; XHCI WP25 ✅ ✅ Abgeschlossen
M6 — Netzwerk TCP-Stack WP16-TCP ✅ (E1000, DHCP, ARP, TCP, Syscalls 180–184) POSIX-Socket-API offen
M7 — Lyra-Agent Lyra-Domäne (Ring-3 privilegierter LLM-Dienst, kein kernel/ai.lyx) Offen
M8–M10 Semantic OS Layer, Aerospace Safety, Distribution Offen

Der vollständige Fahrplan mit Work-Package-Details liegt unter doku/fahrplan.md im Repository.

Letzte Aktualisierung: 2026-06-25