====== Memory Scrubbing ===== **Memory Scrubbing** ist ein präventiver Integritätsmechanismus, der das **Code-Segment im RAM periodisch auf Bit-Flips prüft** — bevor korrumpierte Instruktionen ausgeführt werden. Er läuft als Hintergrundprozess und ist auf Systemen sinnvoll, die kosmischer Strahlung ausgesetzt sind (Luft- und Raumfahrt) oder bei denen SRAM-Fehler durch Alterung und Temperatur auftreten können. Im Unterschied zu [[lyx_-_programmiersprache:do-178c:software-lockstep|Software Lockstep]] schützt Memory Scrubbing nicht die **Berechnung** (CPU-Ebene), sondern den **gespeicherten Maschinencode** (Speicher-Ebene). Beide Mechanismen sind komplementär. → Verwandt: [[lyx_-_programmiersprache:do-178c:triple_modular_redundancy|TMR]] · [[lyx_-_programmiersprache:do-178c:software-lockstep|Software Lockstep]] · [[lyx_-_programmiersprache:do-178c:meta_safe|.meta_safe ELF-Sektion]] · [[lyx_-_programmiersprache:do-178c|DO-178C Hauptseite]] ---- ===== 1. Aktivierung ===== // Unit-Level — schützt alle Funktionen der Unit @integrity(mode: scrubbed, interval: 100) unit nav.core; import std.io; * **mode: scrubbed** — aktiviert den periodischen CRC32-Sweep des Code-Segments * **interval: 100** — alle 100 ms einen vollständigen Sweep durchführen Der ''interval''-Wert ist ein Richtwert für die Runtime/den Scheduler. Auf Bare-Metal-Targets mit SysTick wird der Sweep in der SysTick-ISR ausgelöst. ---- ===== 2. Wie der Compiler vorbereitet ===== Der Scrubbing-Mechanismus setzt voraus, dass der Compiler beim Build eine kryptographische Referenz des Code-Segments einbettet: - **Code-Generierung**: Backend erzeugt vollständigen Maschinencode. - **Sektion anlegen**: Die ''.meta_safe'' ELF-Sektion wird mit Platzhaltern angelegt. - **CRC32-Berechnung**: Der Compiler berechnet den CRC32 (IEEE 802.3) über das fertige Code-Segment. - **Post-Patching**: Die drei Hashslots in ''.meta_safe'' werden mit dem echten Wert überschrieben. Die drei Kopien liegen **4096 Byte voneinander entfernt** — ein lokaler Speicherdefekt kann nicht alle drei gleichzeitig korrumpieren. → Vollständige Struktur der ''.meta_safe'' Sektion: [[lyx_-_programmiersprache:do-178c:meta_safe|.meta_safe ELF-Sektion]] ---- ===== 3. Laufzeit-Ablauf ===== Beim Programmstart und in regelmäßigen Abständen: Code-Segment im RAM ┌─────────────────────────────────────────────────────┐ │ fn ComputeFlightPath() { … } │ │ fn ReadIMU() { … } │ │ … alle Instruktionen der Unit … │ └─────────────────────────────────────────────────────┘ │ │ CRC32 berechnen (periodisch) ▼ Ist-Hash (neu berechnet) │ │ Vergleich gegen alle drei Referenzen ▼ .meta_safe ELF-Sektion ┌────────────────────────────────────────────────────┐ │ hash_copy_1 @ Offset 32 (CRC32: 0xA3F2...) │ │ [4096 Byte Padding] │ │ hash_copy_2 @ Offset 4128 (CRC32: 0xA3F2...) │ │ [4096 Byte Padding] │ │ hash_copy_3 @ Offset 8224 (CRC32: 0xA3F2...) │ └────────────────────────────────────────────────────┘ │ Mehrheitsentscheid (TMR): ≥ 2 von 3 stimmen überein → ✅ OK < 2 übereinstimmend → ⚠ Integritätsfehler ---- ===== 4. VerifyIntegrity() ===== Das Builtin ''VerifyIntegrity()'' löst einen sofortigen manuellen Sweep aus und gibt ''bool'' zurück: @integrity(mode: scrubbed, interval: 100) unit flight_control; import std.io; fn StartupCheck(): void { if (VerifyIntegrity() = false) { // Bit-Flip erkannt — vor dem normalen Betrieb PrintStr("INTEGRITY FAILURE — switching to backup\n"); ActivateBackupComputer(); HaltPrimary(); } PrintStr("Code integrity verified\n"); } fn main(): int64 { StartupCheck(); // Immer zuerst // ... normale Betriebslogik ... return 0; } ''VerifyIntegrity()'' ist das erste, was ein DAL-A-System beim Start aufruft — bevor irgendwelche sicherheitskritischen Berechnungen beginnen. ---- ===== 5. Integration mit dem Scheduler / ISR ===== Auf Bare-Metal-Targets ohne RTOS löst der SysTick-ISR den periodischen Sweep aus: unit cortexm_scrub; @volatile var scrub_tick: int64 := 0; con SCRUB_INTERVAL_MS: int64 := 100; @section(".isr_vector") @no_opt fn SysTick_Handler(): void { scrub_tick := scrub_tick + 1; } fn main(): int64 { // Startup-Check if (VerifyIntegrity() = false) { panic("boot integrity failure"); } var last_scrub: int64 := 0; while (true) { // Anderen Aufgaben verarbeiten ... DoControlCycle(); // Periodischer Scrub if (scrub_tick - last_scrub >= SCRUB_INTERVAL_MS) { last_scrub := scrub_tick; if (VerifyIntegrity() = false) { // Bit-Flip im Code erkannt — Recovery ActivateBackupSystem(); } } } return 0; } Auf FreeRTOS (ESP32) wird der Sweep in einer dedizierten Low-Priority-Task ausgeführt: fn ScrubTask(arg: int64): void { while (true) { vTaskDelay(100); // 100 RTOS-Ticks ≈ 100 ms if (VerifyIntegrity() = false) { ActivateBackupSystem(); } } } ---- ===== 6. Timing-Fenster ===== Zwischen zwei Sweeps besteht ein **ungeschütztes Zeitfenster**: Ein Bit-Flip, der nach einem erfolgreichen Sweep entsteht, wird erst beim nächsten Sweep erkannt. Dieses Fenster ist durch ''interval'' konfigurierbar. ^ Interval ^ Ungeschütztes Fenster ^ CRC-Overhead (typisch) ^ | 10 ms | Max. 10 ms | ~5–15 µs pro Sweep (je nach Code-Segment-Größe) | | 100 ms | Max. 100 ms | Vernachlässigbar | | 1000 ms | Max. 1 s | Minimalster Overhead | Für DAL-A empfiehlt sich ein Interval von **50–100 ms**. Der CRC-Overhead ist proportional zur Größe des Code-Segments und liegt bei typischen Avionik-Units (< 64 kB Code) unter 20 µs. ---- ===== 7. Kombination mit anderen Schutzmechanismen ===== // Maximaler Schutz: Unit mit Scrubbing + kritische Funktionen mit Lockstep + @redundant Daten @integrity(mode: scrubbed, interval: 50) unit autopilot.kernel; @redundant var flight_mode: int64 := 0; @dal(A) @flight_crit @integrity(mode: software_lockstep, interval: 50) @wcet(200) @stack_limit(2048) fn ComputeFlightCommands(state: ^FlightState): FlightCommands { // Berechnung geschützt durch: Lockstep (ALU) + Scrubbing (Code-Segment) + TMR (Daten) // Das ist die Dreifach-Absicherung für DAL-A-Kernfunktionen } ^ Mechanismus ^ Was er schützt ^ Ergänzt ^ | ''@integrity(scrubbed)'' | Code-Segment (Bit-Flip in Instruktionen) | Lockstep, TMR | | ''@integrity(software_lockstep)'' | Berechnungen (Latch-Fehler in der CPU) | Scrubbing, TMR | | ''@redundant'' | Kritische Datenwerte (Bit-Flip im RAM) | Scrubbing, Lockstep | ---- ===== 8. DAL-Empfehlung ===== ^ DAL ^ Memory Scrubbing ^ Begründung ^ | A | **Zwingend** | Nachweis gegen Single-Point-Failure im Code-Speicher | | B | **Empfohlen** | SEU-Risiko rechtfertigt Overhead | | C | Optional | Sinnvoll auf strahlungsexponierten Targets | | D/E | Nicht nötig | Kein SEU-Schutz gefordert | ---- Letzte Aktualisierung: 2026-05-22