====== Lyx OS – LBF: Lyx Binary Format ====== Das **Lyx Binary Format (LBF)** ist das native ausführbare Binärformat von Lyx OS. Es ersetzt ELF/PE für alle Programme die mit ''lyxc --target=lyxos'' kompiliert werden, und ist von Grund auf für KI-native Architekturen und das [[lyxos:iofs|Island & Ocean File System (IOFS)]] entworfen. **Version:** 1.1 · **Magic:** ''LYX!'' (0x4C 0x59 0x58 0x21) LBF ist das ausführbare Binärformat von Lyx OS. Anders als ELF oder PE wird ein LBF-Binary auf nativem IOFS **ohne eine einzige Speicher-Kopie** ausgeführt — der Kernel trägt die physischen Disk-Adressen direkt in die CPU-Seitentabelle ein. Block 0 (Genesis-Block) enthält zusätzlich einen strukturierten KI-Kontext, der dem Betriebssystem vor der ersten Ausführung mitteilt was das Programm tut und welche Rechte es benötigt. → [[lyxos:anwendungen|Anwendungen entwickeln]] · [[lyxos:kernel|Kernel-Interna]] · [[lyxos:start|Übersicht]] ---- ===== 0. Implementierungsstand (nachgemessen 2026-08-27 mit lyxc 1.1.11B) ===== **Zwei Emit-Modi — NICHT verwechseln:** ^ Flag-Kombination ^ Erzeugtes Format ^ Magic ^ Zweck ^ | ''lyxc prog.lyx %%--%%target=lyxos'' | Natives LYX! (x86-64-Maschinencode) | ''LYX!'' (0x4C595821) | Produktiv — läuft auf Lyx OS | | ''lyxc prog.lyx %%--%%target=lyxos %%--%%emit=lbf'' | IR-Bytecode LBF\0 | ''LBF\0'' (0x4C424600) | Simulation/Test — kein nativer Code | Der Rest dieser Seite beschreibt das **native LYX!-Format** (Produktionspfad). ==== Was heute trägt ==== * ''%%--%%target=lyxos'' erzeugt nativen x86-64-Maschinencode im LYX!-Format; ''lyxc'' übersetzt sich selbst dorthin. * **Mehrere Sektionen sind umgesetzt** — Compiler **und** Kernel. Der Compiler legt je Sektion einen ''SECTION_MAP''-Eintrag im Genesis-Block ab, der Loader (''kernel/lbf_exec.lyx'') liest ihn und trennt ''.text'', ''.rodata'' und ''.data'' beim Einhängen. * **W^X ist umgesetzt**, konservativ: der Loader führt eine Schreibbarkeitskarte über alle Seiten des Abbilds. Weil die Nutzlast eines Blocks 4032 Byte lang ist und damit **nicht** auf Seitengrenzen fällt, kann eine Seite Bytes aus zwei Sektionen enthalten — deshalb gilt: eine Seite ist beschreibbar, sobald **irgendein** Byte darin zu einer beschreibbaren Sektion gehört. Nur Seiten, die vollständig von Nur-Lese-Sektionen gedeckt sind, werden schreibgeschützt eingehängt (''PTE_P_U'' statt ''PTE_P_W_U''). * **''.bss'' wird vom Kernel genullt** (Sektionstyp 4, keine Daten in der Datei). * **Rechte kommen aus dem Manifest.** Die ''CAPABILITIES''-TLV wird beim Laden auf die ''PLEDGE''-Bits des Kernels abgebildet; ein LBF ohne Angabe bekommt **nur** ''PLEDGE_STDIO'' — fail-closed. * VA-Layout: Nutzlast 4032-B-gepackt, zusammenhängend ab ''0x400000''; ''entry_point'' ist die volle virtuelle Adresse (normal ''0x400000'' = ''_start''). Stapel 16 KB, Seitenkarte bis 8192 Seiten (= 32 MB Abbild). ==== Noch offen ==== * IOFS-Zero-Load-Executor (Abschnitt 6 beschreibt den Entwurf, nicht den Stand) * ARM64-LYX! (WP-5) * Signaturen und die Vertrauenskette aus Abschnitt 5 * Modus B (Sub-Page-Packing) — es gibt kein Flag dafür, siehe Abschnitt 2 ---- ===== 1. Warum ein neues Binärformat? ===== ELF und PE tragen jahrzehntelangen Ballast: komplexe Relokationstabellen, dynamische Linker, Sektions-Parsing zur Laufzeit — und keinerlei semantische Selbstbeschreibung. LBF bricht damit auf drei Ebenen: **Physisch:** LBF ist exakt auf das 4096-Byte-Page-Raster der NVMe-Hardware und der CPU ausgerichtet. Auf nativem IOFS lädt der Kernel keine Segmente in den RAM — er trägt die physischen Sektoradressen (LBAs) direkt in die Page Tables (CR3) ein. Die CPU feuert den Maschinencode ohne eine einzige Kopie. **Semantisch:** Block 0 (der Genesis-Block) enthält einen strukturierten KI-Kontext-Pool, der der System-KI vor der ersten Ausführung mitteilt: was das Programm tut, welche Hardware-Erweiterungen es benötigt, welche Abhängigkeiten es deklariert, und ob die kryptografische Vertrauenskette intakt ist. **Dual-Portabel:** Auf Legacy-Dateisystemen verhält sich LBF wie eine flache, sequentielle Binärdatei (POSIX-Loader ''lbf_run''). Auf nativem IOFS injiziert der Kernel die 4-KB-Blöcke direkt als Datenknoten in den Graphen. Dasselbe Binary, zwei Lademodi, null Overhead. ---- ===== 2. Zwei Layout-Modi ===== ==== Modus A — Striktes Alignment (Standard) ==== Jede logische Sektion (''.text'', ''.data'', ''.rodata'') beginnt an einer physischen 4096-Byte-Grenze. Optimal für große, monolithische Anwendungen: maximale Page-Table-Mapping-Performance, jeder Block direkt als IOFS-Page importierbar. Block 0: Genesis-Block (4096 Bytes) Block 1: .text [0] Block 2: .text [1] Block 3: .rodata [0] ← neue 4-KB-Grenze, eigene Page Block 4: .data [0] ← neue 4-KB-Grenze, eigene Page ==== Modus B — Sub-Page Packing ==== > **Ein Flag dafür gibt es nicht.** ''%%--%%lbf-packed'' wird auch von ''lyxc 1.1.11B'' abgewiesen: ''lyxc: unbekannter Schalter '%%--%%lbf-packed''' — mit dem Verweis auf ''lyxc %%--%%help''. Der folgende Abschnitt beschreibt den vorgesehenen Modus, nicht den heutigen Stand — ''%%--%%target=lyxos'' erzeugt Modus A. Für Kleinstprogramme und Microservices. Sektionen mit identischen Zugriffsrechten werden in dieselbe 4-KB-Page gepackt. Erst wenn sich die Schutzrechte ändern, beginnt ein neuer Block. **Packing-Regel:** ''.text'' (R/X) und ''.rodata'' (R) können in eine gemeinsame Page. ''.data'' (R/W) erzwingt immer eine neue 4-KB-Grenze. Block 0: Genesis-Block (4096 Bytes) Block 1: .text + .rodata zusammen (beide R, ≤ 4032 Bytes) Block 2: .data [0] ← Grenze wegen R/W Der Compiler setzt ''lbf_flags |= LBF_FLAGS_PACKED'' im Genesis-Header. Der Loader (POSIX und IOFS) liest dieses Bit und wendet die korrekten Schutzrechte anhand des Section-Descriptor-TLV (Typ ''0x08'') pro Sub-Segment an. ---- ===== 3. Genesis-Block ===== > **Hier weichen Entwurf und Umsetzung voneinander ab.** Die Byte-Tabelle weiter unten ist die **Entwurfsfassung** aus der Formatspezifikation. Was ''lyxc'' heute erzeugt und was ''kernel/lbf_exec.lyx'' liest, sieht anders aus — beides steht hier, damit niemand aus der falschen Tabelle liest. ==== Umsetzung: was heute in der Datei steht ==== Jeder 4096-Byte-Block beginnt mit einem **64-Byte-Blockkopf**; darauf folgen **4032 Byte Nutzlast**. Das gilt auch für Block 0 — die Genesis-Felder liegen also **hinter** dem Blockkopf. ^ Datei-Offset ^ Feld (Nutzlast-Versatz) ^ Größe ^ Bedeutung ^ | 0x0000 | ''magic'' | 4 | ''"LYX!"'' | | 0x0040 | ''content_type'' (+0x00) | 1 | 1 = ausführbar | | 0x0041 | ''target_arch'' (+0x01) | 1 | 1 = x86-64 | | 0x0044 | ''entry_point'' (+0x04) | 8 | volle virtuelle Adresse, normal ''0x400000'' | | 0x0058 | ''stack_size'' (+0x18) | 4 | Stapelgröße in Byte | | 0x00AC | ''tlv_offset'' (+0x6C) | 2 | Anfang des TLV-Pools, Vorgabe ''0x0080'' | | 0x00C0 | TLV-Pool (+0x80) | Rest | Type-Length-Value, siehe unten | Nachgemessen an einem Programm mit ''@capabilities([fs.read, hardware.block])'', übersetzt mit ''lyxc 1.1.11B'': content_type 1 arch 1 entry 0x400000 stack_size 131072 tlv_offset 0x80 typ 5 len 8 CAPS 0x41 typ 8 len 2 0000 typ 9 len 8 SECTION_MAP start_block=1 count=2 typ=1 prot=5 typ 9 len 8 SECTION_MAP start_block=2 count=2 typ=2 prot=4 typ 9 len 8 SECTION_MAP start_block=3 count=2 typ=3 prot=3 Die **Typnummern der Umsetzung** weichen von der Entwurfsliste in Abschnitt 4 ab: ^ Typ ^ Umsetzung (''kernel/lbf_exec.lyx'') ^ Entwurfsliste ^ | 5 | **CAPABILITIES** (u64) | EXT_META_PTR | | 9 | **SECTION_MAP**: ''start_block''(u32), ''count''(u16), ''type''(u8), ''prot''(u8) | reserviert für DWARF-Unwind | | 7 | — (nicht erzeugt) | CAPABILITIES | Im ''SECTION_MAP''-Eintrag wertet der Kernel heute **ein** Bit aus: ''prot'' Bit 1 (''LBF_PROT_WRITE'') entscheidet, ob die Seiten beschreibbar eingehängt werden. Sektionstyp 4 ist ''.bss'' — dafür stehen keine Daten in der Datei, der Kernel nullt den Bereich. ---- ==== Entwurfsfassung: 96-Byte-Header + 4000-Byte-Pool ==== //Diese Tabelle beschreibt die geplante Fassung, nicht den heutigen Stand.// Block 0 als vollständiges Kontrollzentrum: 96-Byte-Header gefolgt von einem 4000-Byte-TLV-Pool. ┌─────────────────────────────────────────────────────────────────┐ │ 0x0000–0x000F Core Machine Header (16 Bytes) │ │ 0x0010–0x005B Compiler Provenance Block (76 Bytes) │ │ 0x005C–0x005F Layout Flags & KI-Offset (4 Bytes) │ ├─────────────────────────────────────────────────────────────────┤ │ 0x0060–0x0FFF KI-Semantik-Register / TLV-Pool (4000 Bytes) │ └─────────────────────────────────────────────────────────────────┘ ==== Vollständige Byte-Tabelle ==== ^ Offset ^ Größe ^ Typ ^ Feld ^ Beschreibung ^ | 0x0000 | 4 | ''Char[4]'' | ''magic'' | ''"LYX!"'' (0x4C 0x59 0x58 0x21) | | 0x0004 | 1 | ''uint8'' | ''format_version'' | LBF-Format-Version: ''0x01'' | | 0x0005 | 1 | ''uint8'' | ''target_arch'' | ''0x01''=x86-64, ''0x02''=ARM64, ''0x03''=RISC-V | | 0x0006 | 2 | ''uint16'' | ''os_version'' | Mindest-Kernel-Version (''0x0100'' = v1.0) | | 0x0008 | 8 | ''uint64'' | ''entry_point'' | Virtuelle CPU-Startadresse | | 0x0010 | 16 | ''uint8[16]'' | ''compiler_name'' | ''"lyxc"'' + 12 Bytes Padding | | 0x0020 | 4 | ''uint32'' | ''compiler_version'' | ''Major<<16 %%|%% Minor<<8 %%|%% Patch'' | | 0x0024 | 8 | ''uint64'' | ''compiled_at'' | Kompilierzeitpunkt (µs seit Unix-Epoch) | | 0x002C | 16 | ''uint8[16]'' | ''compiler_instance_sn'' | UUID der Compiler-Instanz (RFC 4122 v4) | | 0x003C | 32 | ''uint8[32]'' | ''source_sha256'' | SHA-256 aller ''.lyx''-Eingabedateien (konkateniert) | | 0x005C | 2 | ''uint16'' | ''lbf_flags'' | Bit 0: ''LBF_FLAGS_PACKED''; Bits 1–15: Reserviert | | 0x005E | 2 | ''uint16'' | ''ki_context_offset'' | Byte-Offset zum TLV-Bereich; Standard: ''0x0060'' | | 0x0060 | 4000 | ''uint8[]'' | ''ki_context'' | TLV-Pool (Typen 0x01–0x0F) | con LBF_FLAGS_PACKED : uint16 := 1 con LBF_ARCH_X86_64 : uint8 := 0x01 con LBF_ARCH_ARM64 : uint8 := 0x02 con LBF_ARCH_RISCV : uint8 := 0x03 ==== Dateistruktur ab Block 1 ==== Block 0 folgen die Code- und Daten-Blöcke. Jeder Block ist exakt 4096 Bytes, ohne eigenen Block-Header. BLOCK 0 Genesis-Block BLOCK 1+ .text [0..N] R/X — Maschinencode BLOCK N+1 .rodata [0..] R — Konstanten, String-Literale BLOCK M+1 .data [0..] R/W — initialisierte globale Variablen BLOCK K+1 .bss R/W — Kernel setzt auf 0, kein Inhalt auf Disk Im Modus B können ''.text'' + ''.rodata'' in einem gemeinsamen Block stehen; die Aufteilung steht im Section-Descriptor-TLV (Typ ''0x08''). ---- ===== 4. TLV-Framework (KI-Semantik-Register) ===== Der 4000-Byte-Pool ab Offset ''0x0060'' verwendet eine Type-Length-Value-Struktur: [Type: uint8 (1 Byte)] [Length: uint16 LE (2 Bytes)] [Value: Length Bytes] Overhead pro Eintrag: 3 Bytes Reichen 4000 Bytes nicht aus, verweist TLV ''0x05'' (EXT_META_PTR) auf eine Continuation-IOFS-Page. Das Framework ist damit für beliebig komplexe Programme unbegrenzt erweiterbar. > **Die Nummern in diesem Abschnitt sind die Entwurfsfassung.** Umgesetzt sind heute **Typ 5 = CAPABILITIES** und **Typ 9 = SECTION_MAP**; ''lyxc 1.1.11B'' erzeugt genau diese beiden (dazu einen leeren Typ 8). Die Zuordnung steht in Abschnitt 3 unter „Umsetzung"; der Kernel liest sie in ''kernel/lbf_exec.lyx''. **Typen 0x09–0x0F** sind im Entwurf reserviert: ''0x09'' (DWARF-Unwind-Frame) und ''0x0A'' (Debug-Symboltabelle) sind für v1.2 geplant (siehe [[#10-versionierung|Versionstabelle]]). Typen ''0x0B–0x0F'' sind unbelegt und dürfen von Custom-Toolchains genutzt werden, sofern ein Vendor-Präfix in HUMAN_INTENT (TLV ''0x01'') deklariert ist. ==== TLV 0x01 — HUMAN_INTENT ==== **Payload:** UTF-8-Freitext, max. 512 Bytes. Enthält die semantische Beschreibung des Programms. Der Compiler extrahiert ihn aus ''///''‑Doc-Comments über ''main()'': /// Berechnet die CRC32C-Prüfsumme für Speichermedien im IOFS. /// Liest Eingabe von stdin, gibt Prüfsumme als Hex auf stdout aus. fn main(): int64 { ... } Nutzen: * Shell gibt dem User ad-hoc Hilfe ohne Man-Pages * Semantische Firewall prüft Intent gegen angefragte Rechte * IOFS Omni-Ingest indexiert ihn für Timeline-Suche * Lyra kündigt dem User an was das Programm tut, bevor ''sys_acc_action'' ausgeführt wird ==== TLV 0x02 — DEP_HASH_GRAPH ==== **Payload:** Array aus Dependency-Deskriptoren à 52 Bytes. Jeder Eintrag enthält: SHA-256 des Dependency-Quellcodes (32 Bytes), Mindest-Version (4 Bytes) und Kurzname/Alias (16 Bytes). Auf IOFS übersetzt der Dependency-Resolver die SHA-256-Hashes via Hash-Index in LPIDs und webt Graph-Kanten (Gewicht ''0xD001'') in den Genesis-Knoten — kein Linker-Lauf. ==== TLV 0x03 — SYM_INTERFACE ==== **Payload:** Array aus kryptografisch verifizierten Funktions-Bindungen. Jeder Eintrag enthält Funktionsname, Parameter-Typen, Rückgabetyp, einen Contract-Hash (SHA-256 der erlaubten Ziel-Insel) und optional den Public Key des erwarteten Signierers. Verhindert Late-Binding-Angriffe: Ein identischer Funktionsname reicht nicht — der Contract-Hash oder Public Key muss übereinstimmen. ==== TLV 0x04 — ISA_EXTENSIONS ==== **Payload:** ''uint64'' Bitmaske der benötigten CPU-Instruktionserweiterungen. con LBF_ISA_AVX2 : uint64 := 1 // Intel AVX2 (256-bit SIMD) con LBF_ISA_AVX512 : uint64 := 2 // Intel AVX-512 (512-bit SIMD) con LBF_ISA_ARM_NEON: uint64 := 4 // ARM NEON / AdvSIMD con LBF_ISA_AMX : uint64 := 8 // Intel AMX (KI-Beschleunigung) con LBF_ISA_SVE : uint64 := 16 // ARM SVE/SVE2 con LBF_ISA_RISCV_V : uint64 := 32 // RISC-V Vector Extension con LBF_ISA_AES_NI : uint64 := 64 // x86 AES-NI (Hardware-Verschlüsselung) con LBF_ISA_SHA_NI : uint64 := 128 // x86 SHA-NI (Hardware-Hashing) Beim Start gleicht die KI diese Maske gegen die CPUID-Register des Kernels ab. Bei Inkompatibilität wird die Ausführung sicher abgefangen statt einen ''SIGILL''-Trap zu riskieren. ==== TLV 0x05 — EXT_META_PTR ==== **Payload:** ''uint64'' LPID (IOFS) oder Block-Index (POSIX). Verweist auf eine Continuation-Page mit weiteren TLV-Daten wenn die 4000 Bytes des Genesis-Blocks erschöpft sind. ==== TLV 0x06 — SOURCE_MAP ==== **Payload:** Git-Commit-SHA1 (20 Bytes), IOFS-LPID (8 Bytes) oder UTF-8-URI (variabel). Ermöglicht dem Kernel-Tracer, CPU-Register und Maschinencode-Zustände direkt in lesbaren Lyx-Quellcode zurückzuübersetzen. Lyra kann bei Abstürzen die verursachende Quellcode-Zeile direkt benennen. ==== TLV 0x07 — CAPABILITIES ==== **Payload:** ''uint64'' Bitmaske der benötigten Kernel-Rechte. con LBF_CAP_FS_READ : uint64 := 1 con LBF_CAP_FS_WRITE : uint64 := 2 con LBF_CAP_NET_SOCKET : uint64 := 4 con LBF_CAP_PROC_SPAWN : uint64 := 8 con LBF_CAP_KI_EMBED : uint64 := 16 con LBF_CAP_KI_GRAPH_WRITE: uint64 := 32 con LBF_CAP_SANDBOX_ACCESS: uint64 := 64 con LBF_CAP_AUDIO_MIC : uint64 := 128 con LBF_CAP_PRIVILEGED : uint64 := 9223372036854775808 // Bit 63 Der Compiler leitet diese Maske automatisch aus den verwendeten ''import''-Statements ab (z.B. ''import std.net.socket'' → ''LBF_CAP_NET_SOCKET''). Die Semantische Firewall prüft: Fordert das Binary Capabilities an die sein deklarierter HUMAN_INTENT nicht rechtfertigt? ==== TLV 0x08 — SECTION_DESCRIPTOR ==== **Payload:** Array aus Section-Deskriptoren à 8 Bytes. ^ Offset ^ Größe ^ Feld ^ Beschreibung ^ | 0x00 | 2 | ''block_start'' | Erster Block-Index dieser Sektion | | 0x02 | 2 | ''block_count'' | Anzahl Blöcke (oder Sub-Block-Anteil im Packed-Modus) | | 0x04 | 1 | ''section_type'' | ''0x01''=''.text'', ''0x02''=''.data'', ''0x03''=''.rodata'', ''0x04''=''.bss'' | | 0x05 | 1 | ''protection'' | Bitmaske: ''0x01''=Read, ''0x02''=Write, ''0x04''=Execute | | 0x06 | 2 | ''byte_offset'' | Im Modus B: Startoffset innerhalb des Blocks (0 im Modus A) | ---- ===== 5. Vertrauenskette (5 Schichten) ===== LBF implementiert Supply-Chain-Security durch fünf übereinander liegende Sicherheitsschichten: ^ Schicht ^ Mechanismus ^ Angriff der verhindert wird ^ | 1 — Bit-Rot | SHA-256 über alle Quelldateien (''source_sha256'') | Stille Bit-Korruption auf Disk | | 2 — Source-Herkunft | ''source_sha256'' bricht wenn Maschinencode geändert wird | Nachträgliche Code-Manipulation | | 3 — Compiler-Vertrauen | Blacklist kompromittierter Compiler-UUIDs in der IOFS Panic-Sandbox | Kompromittierte Build-Toolchain | | 4 — Contract-Linking | TLV ''0x03'' (SYM_INTERFACE): Contract-Hash oder Public Key muss stimmen | Late-Binding-Angriffe via Namens-Kollision | | 5 — Intent-Kohärenz | Semantische Firewall prüft HUMAN_INTENT gegen CAPABILITIES | Tarnung von Malware als harmlose App | **Prüfreihenfolge beim LBF-Import auf IOFS:** 1. Genesis-Block lesen; format_version prüfen (== 0x01) 2. Compiler-UUID gegen Blacklist prüfen 3. ISA_EXTENSIONS gegen CPUID des Kernels prüfen 4. Intent + Capabilities auf Kohärenz prüfen (Semantische Firewall) 5. DEP_HASH_GRAPH auflösen → Dependency-LPIDs via Hash-Index 6. SYM_INTERFACE-Contracts verifizieren 7. IOFS-Pages für alle Blöcke anlegen, Graph-Kanten weben ---- ===== 6. Zero-Load auf nativem IOFS ===== Das Herzstück des Formats: auf IOFS wird kein Segment in den RAM kopiert. > **Hintergrund für Junior-Entwickler:** ''CR3'' ist das CPU-Register das auf die Seitentabelle (Page Table) des laufenden Prozesses zeigt — es bestimmt welche virtuellen Adressen auf welche physischen RAM-Seiten zeigen. ''LBA'' (Logical Block Address) ist die physische Sektor-Adresse auf der NVMe-SSD. ''PTE'' (Page Table Entry) ist ein einzelner Eintrag in dieser Tabelle. ''CPUID'' ist eine x86-Instruktion mit der die CPU ihre eigenen Fähigkeiten (AVX, AES-NI usw.) meldet. 1. Kernel liest Genesis-Block (IOFS-Page Typ=0x04) → Vertrauenskette durchlaufen → ISA_EXTENSIONS gegen CPUID validieren 2. Kernel erstellt neues CR3-Page-Table-Root 3. Section-Descriptor-TLV (0x08) bestimmt VA-Layout: .text: 0x0000000000400000 + block_index × 4096 .rodata: folgt direkt nach .text .data: folgt direkt nach .rodata .bss: kein Block auf Disk — Kernel alloziert zeroed Frames 4. Für jeden Block (Block 1..N): lba = lip_get(block_lpid) → O(1) LIP-Übersetzung pte.phys_addr = lba × 4096 → LBA direkt als physische Adresse pte.flags = section.prot → R/W/X via NX-Bit PTE in CR3 schreiben → kein Kopieren, kein Parsen 5. Stack allozieren (Kernel-Default: 128 KB) 6. CPU springt zu entry_point → Alle Pages bereits gemappt — kein erster Page-Fault → Kein ELF-Interpreter, kein ld.so, kein Relokations-Loop **Ladezeit:** O(n) mit n = Anzahl Blöcke, ausschließlich O(1)-LIP-Lookups und PTE-Schreibvorgänge. Kein Parser, kein Segment-Allokator. ---- ===== 7. POSIX-Lademodus ===== Auf Linux, macOS und Windows läuft LBF über den Kompatibilitätslader ''lbf_run''. Die semantischen Sicherheitsschichten (Semantische Firewall, Graph-Kanten) entfallen; ''lbf_run'' ist ein Entwicklungs- und Portabilitätspfad, kein Produktionspfad. 1. Prüfe Magic "LYX!" an Byte 0 2. format_version prüfen (== 0x01) 3. Compiler-UUID gegen ~/.lyx/compiler_blacklist.bin prüfen 4. ISA_EXTENSIONS gegen CPUID prüfen 5. Section-Descriptor-TLV (0x08) auslesen 6. Blöcke 1..N via mmap() mit korrekten Schutzrechten mappen: .text: PROT_READ | PROT_EXEC .rodata: PROT_READ .data: PROT_READ | PROT_WRITE .bss: mmap(MAP_ANON) → zeroed 7. DEP_HASH_GRAPH → POSIX-Pfad-Auflösung via LD_LIBRARY_PATH 8. Springe zu entry_point ---- ===== 8. IOFS-Integration ===== Beim Import via ''lbf_import'' legt der Kernel für jeden 4-KB-LBF-Block eine [[lyxos:iofs|IOFS]]-Page an: * **Block 0 (Genesis):** IOFS-Page Typ=''0x04'' (''LBF_Executable''), CRC32C über gesamte Page, LPID gesetzt * **Blöcke 1..N (Code/Daten):** IOFS-Pages Typ=''0x02'' (Data) Graph-Kanten verbinden die Blöcke und Abhängigkeiten: con IOFS_EDGE_LBF_CHAIN : int64 := 0xB001 // Genesis → Block 1 → Block 2 → ... con IOFS_EDGE_LBF_DEP : int64 := 0xD001 // Genesis → externe Bibliotheks-Genesis **IOFS-Page vs. LBF-Genesis:** Beide tragen ''LYX!'' an Byte 0. Die Unterscheidung erfolgt über Byte ''0x0004'': Wert ''0x01'' = LBF Genesis-Block (''format_version''); Wert ''0x02''–''0xFF'' = IOFS-Page-Typ. ---- ===== 9. Compiler-Flags und CLI ===== # Natives LYX! (Maschinencode) — Produktionspfad lyxc main.lyx --target=lyxos -o main.lbf # IR-Bytecode LBF\0 — NUR Simulation/Test, kein nativer Code! lyxc main.lyx --target=lyxos --emit=lbf -o main.lbf.ir # Cross-Compilation lyxc main.lyx --target=arm64 -o main_arm.lbf # Debug-LBF (TLV 0x06 zeigt auf lokale .lyx-Dateien) lyxc main.lyx --target=lyxos --debug -o main.lbf # Genesis-Block, TLV-Pool und Sektionen inspizieren lbfdump -x main.lbf # IR-Bytecode disassemblieren lbfdump -d main.lbf.ir → Alle Optionen des Inspektors: [[lyx_-_programmiersprache:tools:lbfdump|lbfdump]] > **Diese früher hier genannten Aufrufe gibt es nicht** (erneut nachgemessen mit lyxc 1.1.11B): > > * ''%%--%%lbf-packed'' (Sub-Page-Packing, Modus B) und ''%%--%%isa=…'' — beide werden mit ''unbekannter Schalter'' und Exit 2 abgewiesen. > * Die Werkzeuge ''lbf_dump'', ''lbf_run'' und ''lbf_import'' sind nicht installiert. Für die Inspektion gibt es ''lbfdump''; eine Prüf-Option für CI (''%%--%%verify-only'') hat es nicht — der Genesis-Block nennt aber die gespeicherte CRC32C, die sich mit ''-f'' ablesen lässt. ---- ===== 10. Versionierung ===== ^ Version ^ Inhalt ^ | v1.0 | Erster Entwurf: Genesis-Header, TLV-Framework, Zero-Load auf IOFS | | **v1.1** | **Aktuell.** Magic "LYX!", 96-Byte-Header, Modus A/B, ''ISA_EXTENSIONS'', ''SYM_INTERFACE'', ''EXT_META_PTR'', ''SOURCE_MAP'', Vertrauenskette auf 5 Schichten | | v1.2 | TLV ''0x0A'': Debug-Symboltabelle. **Achtung:** ''0x09'' ist in der Umsetzung bereits als ''SECTION_MAP'' belegt — der geplante DWARF-Unwind-Frame braucht eine andere Nummer | | v1.3 | Multi-Arch-Fat-Binaries (x86-64 + ARM64 in einer Datei) | | v2.0 | LAB (Lyx AI Binary): Genesis-Block enthält ausführbares LLM-Gewichts-Fragment | Letzte Aktualisierung: 2026-06-25 Letzte Aktualisierung: 2026-08-27 — Stand gegen ''lyxc 1.1.11B'' und ''kernel/lbf_exec.lyx'' nachgemessen: mehrere Sektionen und W^X sind umgesetzt (''SECTION_MAP''-TLV, Schreibbarkeitskarte je Seite), die Rechte kommen fail-closed aus der ''CAPABILITIES''-TLV. Genesis-Layout der Umsetzung ergänzt (64-Byte-Blockkopf, Felder ab +0x40, TLV-Pool ab 0xC0) und von der Entwurfsfassung getrennt; abweichende TLV-Nummern (5 statt 7, 9 statt reserviert) benannt.