====== ELF-Sektion: .meta_safe ====== Die ''.meta_safe''-Sektion ist eine feste Datenstruktur innerhalb der ELF64-Binärdatei, die der Lyx-Compiler automatisch erzeugt, wenn eine Unit mit ''@integrity'' annotiert ist. Sie ist die **Vertrauensverankerung** für den [[lyx_-_programmiersprache:do-178c:memory-scrubbing|Memory-Scrubbing]]-Mechanismus und den [[lyx_-_programmiersprache:do-178c:triple_modular_redundancy|TMR]]-Mehrheitsentscheid über die Code-Referenzhashes. → Verwandt: [[lyx_-_programmiersprache:do-178c:memory-scrubbing|Memory Scrubbing]] · [[lyx_-_programmiersprache:do-178c:triple_modular_redundancy|TMR]] · [[lyx_-_programmiersprache:do-178c|DO-178C Hauptseite]] ---- ===== 1. Gesamtstruktur (8232 Byte) ===== Die Sektion hat eine feste Größe von **8232 Byte**. Die drei CRC32-Hashes liegen jeweils **4096 Byte** voneinander entfernt — eine Standard-Speicherseite auf den meisten Architekturen. Ein lokaler Speicherdefekt (fehlerhafte Speicherzeile, Hot-Bit) kann dadurch nicht zwei Hashes gleichzeitig korrumpieren. Offset Größe Feld Typ Beschreibung ───────────────────────────────────────────────────────────────────────── 0x0000 8 B code_start_va uint64 LE Virtuelle Startadresse des Code-Segments 0x0008 8 B code_end_va uint64 LE Virtuelle Endadresse des Code-Segments 0x0010 4 B mode uint32 LE Integritätsmodus: 1=lockstep, 2=scrubbed, 3=hw_ecc 0x0014 4 B interval_ms uint32 LE Sweep-Intervall in Millisekunden 0x0018 8 B recovery_ptr uint64 LE Adresse des Recovery-Handlers (0 = nicht gesetzt) 0x0020 4 B hash_copy_1 uint32 LE CRC32 (IEEE 802.3) des Code-Segments — Kopie 1 0x0024 4092 B padding_1 — Null-Bytes (Seitentrennung) 0x1020 4 B hash_copy_2 uint32 LE CRC32 — Kopie 2 0x1024 4092 B padding_2 — Null-Bytes 0x2020 4 B hash_copy_3 uint32 LE CRC32 — Kopie 3 0x2024 4 B padding_end — Abschluss-Padding (gesamt: 8232 Byte) ---- ===== 2. Modus-Werte ===== ^ Wert (uint32 LE) ^ Modus ^ Bedeutung ^ | 1 | ''software_lockstep'' | Instruktions-Redundanz für ALU/FPU — kein periodischer Sweep | | 2 | ''scrubbed'' | Periodischer CRC32-Sweep des Code-Segments | | 3 | ''hardware_ecc'' | Vertrauen auf Hardware-ECC — kein Software-Sweep | Bei ''software_lockstep'' wird ''.meta_safe'' trotzdem erzeugt (Hashes als Referenz), der Sweep-Mechanismus ist aber deaktiviert. ---- ===== 3. Compiler-Workflow (Post-Patching) ===== Die CRC32-Hashes können erst nach der vollständigen Code-Generierung berechnet werden — ein Henne-Ei-Problem. Lyx löst es durch einen zweistufigen Build: 1. Code-Generierung ┌─────────────────────────────────────────┐ │ Backend erzeugt Maschinencode │ │ .meta_safe wird mit Platzhaltern (0x00) │ │ angelegt und ins ELF eingebettet │ └────────────────────┬────────────────────┘ │ 2. CRC32-Berechnung ┌─────────────────────────────────────────┐ │ Compiler liest fertiges Code-Segment │ │ Berechnet CRC32 (IEEE 802.3) über │ │ [code_start_va … code_end_va] │ └────────────────────┬────────────────────┘ │ 3. Post-Patching ┌─────────────────────────────────────────┐ │ Compiler überschreibt in der ELF-Datei: │ │ Offset 0x20: hash_copy_1 = CRC32 │ │ Offset 0x1020: hash_copy_2 = CRC32 │ │ Offset 0x2020: hash_copy_3 = CRC32 │ └─────────────────────────────────────────┘ Das fertige ELF enthält drei identische, korrekte Hashes in ''.meta_safe''. ---- ===== 4. Sektion im Linker-Script ===== Für Bare-Metal-Targets muss das Linker-Script ''.meta_safe'' explizit platzieren. Die drei Hash-Kopien sollten auf physisch verschiedene Speicherbereiche verteilt sein — bei SRAM-Targets auf verschiedene Speichermodule oder -bänke, sofern vorhanden: /* Linker-Script-Ausschnitt (ARM Cortex-M, STM32F4) */ /* Flash-Layout */ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 192K SRAM2 (rwx) : ORIGIN = 0x2001C000, LENGTH = 16K BACKUP (rw) : ORIGIN = 0x40024000, LENGTH = 4K } SECTIONS { /* Normaler Code im Flash */ .text : { *(.isr_vector) *(.text*) *(.rodata*) } > FLASH /* .meta_safe nach dem normalen Code */ .meta_safe : { KEEP(*(.meta_safe)) } > FLASH /* TMR-Datenkopien auf physisch verschiedene Speicher */ .tmr_a : { *(.tmr_a) } > SRAM .tmr_b : { *(.tmr_b) } > SRAM2 .tmr_c : { *(.tmr_c) } > BACKUP } > **Wichtig:** ''.meta_safe'' selbst muss im **Flash** (nicht im RAM) liegen — Flash-Speicher ist resistenter gegen SEUs als SRAM und wird typischerweise von der Hardware-ECC des MCUs geschützt. Ein Bit-Flip in den Referenzhashes im Flash ist unwahrscheinlicher als im SRAM. ---- ===== 5. Manuell verifizieren ===== Der CRC32 in ''.meta_safe'' lässt sich nach dem Build unabhängig verifizieren — ein wichtiger Schritt in der DO-178C-Qualifikationskette: // Variante 1: Lyx-eigenes Tool // lyxc --verify-integrity flight_control.elf // // Ausgabe: // .meta_safe found at offset 0x12400 (8232 bytes) // code_start_va: 0x08000200 // code_end_va: 0x08012340 // mode: scrubbed (2), interval: 100 ms // hash_copy_1: 0xA3F2E811 ✓ // hash_copy_2: 0xA3F2E811 ✓ // hash_copy_3: 0xA3F2E811 ✓ // Recomputed CRC: 0xA3F2E811 ✓ // INTEGRITY VERIFIED // Variante 2: Unabhängige Verifikation mit Standard-Tools // readelf -S flight_control.elf | grep meta_safe // → zeigt Offset und Größe // // objcopy --dump-section .meta_safe=meta.bin flight_control.elf // → exportiert die Sektion als Binärdatei // // hexdump -C meta.bin | head // → Offsets 0x20, 0x1020, 0x2020 zeigen die drei Hashes ---- ===== 6. Zugriff aus der Anwendung ===== Neben dem automatischen Hintergrund-Sweep kann die Anwendung explizit abfragen: @integrity(mode: scrubbed, interval: 100) unit flight_kernel; fn StartupSelfTest(): bool { // Liest .meta_safe, berechnet Ist-CRC, führt TMR-Vergleich durch return VerifyIntegrity(); } fn main(): int64 { if (StartupSelfTest() = false) { // Korrumpierter Code — sicheren Zustand einleiten ActivateBackupSystem(); while (true) { } // Hier bleiben bis Reset } // Normaler Betrieb RunMainLoop(); return 0; } ---- ===== 7. Einschränkungen ===== ^ Einschränkung ^ Begründung ^ | ''.meta_safe'' ist kein vollständiger Authentizitätsnachweis | CRC32 ist kein kryptographischer Hash — ein Angreifer kann CRC32 gezielt manipulieren. Das ist kein Angriffsvektor für Avionik (physisch gesichert), aber relevant für andere Kontexte. | | Sweep erkennt keinen Fehler in ''.meta_safe'' selbst | Wenn alle drei Hashes korrumpiert sind (unwahrscheinlich im Flash), liefert der TMR-Vergleich eine falsch positive Aussage. ECC-RAM für Flash ist die Gegenmaßnahme. | | Code-Segment-Grenzen müssen korrekt im Linker-Script definiert sein | Fehlerhafte ''code_start_va''/''code_end_va'' führen zu falschen CRC32-Berechnungen. Immer mit ''--verify-integrity'' nach dem Build prüfen. | ---- Letzte Aktualisierung: 2026-05-22