| Version | 0.15.0 (Phase 15) – SYSTEM_VERSION aus kernel/core/Version.swift, gelesen vom Makefile |
| Stand | 10. November 2026 |
| Architektur | AArch64 (ARMv8-A und neuer), nur 64 Bit, UEFI + ACPI |
| Sprache | Embedded Swift (Kernel, Treiber, Programme); C nur im EFI-Loader; Assembler nur wo nötig |
| Zweck | Roboter (ca. 70 %) und normale Programme wie Server (ca. 30 %). Leitlinien: Echtzeit, Sicherheit und Geschwindigkeit ohne Kompromiss, nur moderne Hardware, kein Altlasten-Code. |
| Hersteller | SOFTrobots GbR · info@softrobots.de · www.softrobots.de |
docs/api/app-api-1.txt, 10.11.2026)@Test) und Gerätetest-Ziele in tools/test-all.sh, gezählt 10.11.2026Wo gemessen: Wenn nicht anders vermerkt, stammen alle Messwerte aus SOFTrobotsVM (eigene macOS-App mit Virtualization.framework, 4 virtuelle CPUs, 4 GiB RAM)
auf dem Host Apple M3 Pro (Mac15,7), 36 GB, macOS 27.0.1, Version 0.15.0, Produktabbild, ruhiger Mac.
Der Benchmark-Lauf vom 08.11.2026, 23:00 Uhr (nach F142 und F143) liegt als docs/benchmarks/2026-11-08-softrobotsvm-benchmark-after-f143.csv vor, das Boot-Log desselben Starts als
…-bootlog-after-f143.txt. Werte aus anderen Läufen nennen ihren Handbuch-Abschnitt (z. B. „Hb. 3.93“); die Messungen vom 10.11.2026 zu Video und Downloads stehen in
docs/benchmarks/video-playback.md und docs/benchmarks/network-download.md. QEMU-Zeiten sind Emulationswerte und hier nicht aufgeführt; Mac-Werte sind als solche gekennzeichnet.
Hervorgehobene Zahlen sind Messwerte. Schätzung markiert jede nicht gemessene Angabe, immer mit Begründung.
1Bilder
2Stand und Grenzen
-M virt, für Fehlersuche und automatische Tests). Es gibt noch keine echte Hardware,
also auch keine echten Motortreiber, Kameras über USB (UVC), SMMU, MTE oder TPM. Alle Zeiten sind VM-Zeiten auf einem Mac; auf einem Roboter-Rechenmodul können sie
anders ausfallen. Echte Hardware ist Phase 16, die Roboter-API mit ROS-2-Bedeutung und Zenoh Phase 17.Was heute funktioniert (Phasen 0–15 abgeschlossen, Stand 10.11.2026)
- Eigener EFI-Loader, Systemkopien A/B mit Updates und automatischem Rückfall; Vorschau zum Herunterladen mit Ablaufdatum (10.11.)
- Kernel mit SMP, tickless Scheduler pro Kern, EDF-Echtzeit mit Zulassungsprüfung, reservierter Echtzeitkern; Systemaufrufe unterbrechbar (F143)
- 16-KiB-Seiten, W^X, PAN/PAC/BTI, Stack-Canaries, Guard Pages
- Programme auf EL0, nur signiert (Ed25519), 32 Rechte aus dem signierten Manifest
- Zero-Copy-IPC über gemeinsame Ringe, 14 nummerierte Systemaufrufe (Formaufruf 13 trägt 24 Module)
- SOFTrobotsFS (Copy-on-Write, B+-Bäume, CRC-32C, AES-256-GCM je Block, Snapshots, Zeitregler)
- SOFTrobotsDB im Dateisystem: Tabellen, Indexe, Abfragen, Joins in WHERE und ORDER BY (09.11.), SQL, Serien, Flugschreiber
- Geräteschutz: Argon2id-Passwort, Wiederherstellungsschlüssel, Bildschirmsperre
- Eigener Netzwerk-Stack: IPv6 (SLAAC), IPv4 (DHCP mit Erneuerung), TCP mit SACK, CUBIC und 1-MiB-Empfangsfenster für Downloads (10.11.), UDP, mDNS
- Eigene Kryptobibliothek, TLS 1.3 als Client und Server (mit KeyUpdate, 09.11.), DNS über HTTPS, NTS-Zeit
- 2D-Desktop mit Fenstern, Menüs, Dock, Hell/Dunkel, Maßstab 2; seit 10.11.: ein Öffnen-/Sichern-Dialog für alle Programme, Fortschritt für alle Programme, Speicherfenster, Fensterknöpfe und Laschen im Dock
- Programme: Files, Web, Image, Reader (PDF), Text, Console, Database, Benchmark, Activity, Settings, Video, Sound, Ask, Develop, Server, chooser (Datei-Dialog) …
- 35 Dateiformate und Codecs mit eigenem Code, u. a. PDF mit Verschlüsselung und Scans, VP9 (1080p auf 3 Kernen), Opus, FLAC (Abschnitt 9)
- Ton: Ausgabe mit Mischer im Kernel, Mikrofon mit immer sichtbarer Anzeige (09.11.)
- Roboter: Not-Halt im Kernel, Aktor-Dienst mit Sicherheitsgrenzen, CAN-FD-Dienst, simulierter 6-Achs-Arm; Develop mit der eigenen Sprache Reflex
- Tests: 540 Host-Testfunktionen (Swift Testing) und 27 automatische Gerätetest-Ziele in QEMU/SOFTrobotsVM (
tools/test-all.sh), dazumake test-preview
Bewusst nicht enthalten
POSIX- oder Linux-Kompatibilität, 32 Bit, BIOS, SATA/IDE, Bluetooth, USB-Klassen außerhalb der Erlaubnisliste, mehrere Benutzer, 3D-Grafik, JavaScript im Browser, andere UI-Sprachen als Englisch. Noch offen oder später: Signaturprüfung des Kernels im Loader, gebündeltes TRIM, QUIC/HTTP/2/HTTP/3, SMMU (DMA-Isolation der Treiberdienste), MTE, TPM-Bindung, GROUP BY über verknüpfte Felder, Datei-Felder in der App-API (Abschnitt 8.5), AV1 (mit Hardware), Opus- und MP3-Aufnahme.
3Architektur-Überblick
Hybrid-Kernel: Alles, was schnell und vertrauenswürdig sein muss – Scheduler, Speicher, IPC, Dateisystem, NVMe, Netzwerk und Krypto – läuft im Kernel (EL1).
Riskante Teile wie USB und Grafik laufen als isolierte Dienste auf EL0. Programme sprechen nur über die System-API mit dem Kernel; eine POSIX- oder Linux-Schicht gibt es bewusst nicht.
Der Kernel ist für die Higher Half (0xFFFFFFFF80000000) gelinkt und an 0x8000_0000 geladen; jeder Abschnitt beginnt auf einer 16-KiB-Grenze und ist W^X abgebildet.
4Programmiersprachen
Gezählt mit wc -l über den Quellbaum (ohne build/, Paket-Caches und docs/), Stand 10.11.2026. Zeilen einschließlich Kommentaren.
| Sprache | Zeilen | Anteil | Wo |
|---|---|---|---|
| Swift (Embedded Swift und Swift für den Mac) | 155 343 | 93,3 % | Kernel 34 766 · Treiber 2 631 · Laufzeit userland/ 49 006 · Programme apps/ 46 717 · Mac-Werkzeuge 7 570 · Host-Tests 14 653 |
| Formsprache (.shape) | 2 240 | 1,3 % | shapes/ 2 144 (23 Dateien) · Programmformen in apps/ 96 |
| Python (nur Werkzeuge) | 2 923 | 1,8 % | Modellkonverter, Training, VP9-Hilfen, Film; läuft nie im System |
| Shell (nur Werkzeuge) | 2 748 | 1,6 % | Testskripte, QEMU-Helfer, Vorschau-Paket, VM-Messung |
| Assembler (AArch64) | 1 622 | 1,0 % | Kernel 1 362: entry.S 343, sysreg.S 383, crypto.S 283, context.S 249, vectors.S 104 · Apps 260: crt0.S 146, infer/asm/kernels.S 114 (sdot) |
| C (EFI-Loader) | 573 | 0,3 % | boot/loader.c |
| C-Header | 568 | 0,3 % | BootInfo, EFI, arch.h, userland/include |
| Reflex (.reflex) | 536 | 0,3 % | Beispiele und Programme für Develop |
| Summe | 166 553 | 100 % | am 09.11.2026: 162 922 – dazu kamen am 10.11. u. a. Datei-Dialog (chooser), Fortschritt, Speicherfenster, Fensterknöpfe, große TCP-Puffer, Vorschau und der VP9-Schleifenfilter auf 3 Kernen |
Embedded Swift
Kernel, Treiber, Dienste und Programme. Toolchain swift.org 6.4.1 (über swiftly), Ziel aarch64-none-none-elf.
Im Kernel: keine Klassen auf heißen Pfaden (kein ARC), kein Heap (-no-allocations), kein async/await, -Osize.
Unsicherer Zeiger- und Registerzugriff nur in kernel/arch/ und drivers/. Hardwareunabhängiger Code in kernel/lib/ läuft auch als normales Swift auf dem Mac (Host-Tests).
Assembler – nur wo nötig
entry.S (Einstieg, EL2→EL1, frühe Seitentabellen), vectors.S (Exception-Vektoren), context.S (Kontextwechsel),
sysreg.S (Systemregister, Swift hat keinen Inline-Assembler) und crypto.S (AES/PMULL für die Platte, SHA-256 mit Prozessorbefehlen – reine Geschwindigkeit).
In Programmen: crt0.S und die sdot-Kerne der Bilderkennung.
C – zwei dokumentierte Ausnahmen
Der EFI-Loader (boot/loader.c, PE/COFF) und Header, die Hardware- und ABI-Strukturen beschreiben (bootinfo.h, arch.h). Die BootInfo-Struktur wird in C per _Static_assert und in Swift per Host-Test geprüft.
Eigene Sprachen
.shape: eine Definition für API, Kernel-Prüfcode, Datenbanktabellen, Ringe und Netz (Werkzeug shapec). Reflex: die Skriptsprache von Develop, im System selbst übersetzt.
5Größen
Kernel (build/kernel/kernel.elf, Build vom 10.11.2026, 17:54 Uhr)
| Abschnitt | Bytes | Größe | Inhalt |
|---|---|---|---|
| .text | 865 776 | 845 KiB | Maschinencode (R X, BTI-geschützt) |
| .rodata | 243 240 | 238 KiB | Konstanten, Schriftmasken der Start-Animation, eingebettete Daten (R) |
| .data | 76 465 | 75 KiB | vorbelegte Variablen (R W, nie X) |
| Geladenes Abbild (Datei-Anteil) | 1 185 481 | 1,13 MiB | was der Loader von der Platte liest |
| .bss | 17 481 728 | 16,67 MiB | feste Tabellen im RAM (Prozesse, Threads, Puffer, seit 10.11. auch 4 TCP-Empfangsringe zu 1 MiB); belegt keinen Platz in der Datei |
| .page_table_pool / .boot_tables / .stack | 2 293 760 | 2,19 MiB | Seitentabellen-Vorrat 2 MiB, frühe Tabellen 64 KiB, Boot-Stack 128 KiB |
| Debug-Informationen (.debug_*) | 6 027 479 | 5,75 MiB | nur zum Symbolisieren; ELF-Datei gesamt 7 655 752 Bytes |
EFI-Loader (build/boot/BOOTAA64.EFI, Build vom 08.11.2026): 17 408 Bytes; 573 Zeilen C.
Disk-Image: 8 GiB (sparse), Partitionen EFI 64 MiB · SYSTEM_A 2 GiB · SYSTEM_B 2 GiB · DATA Rest. Gemessen mit llvm-size; das geladene Kernel-Abbild wuchs seit dem 09.11. um 34 948 Bytes (Datei-Dialog, Vorschau mit Ablaufdatum, große TCP-Puffer, DHCP-Erneuerung), .bss um 4 253 296 Bytes, davon 4 MiB für die vier großen Empfangsringe.
Kernel-Bausteine
Zeilen gezählt (10.11.2026); der Code-Anteil ist eine Schätzung (.text anteilig nach Quellzeilen verteilt, nicht aus der Link-Map gemessen).
| Ordner | Zeilen | ≈ Code | Inhalt |
|---|---|---|---|
kernel/core | 14 924 | ≈ 326 KiB | Kernel-Logik: Scheduler, Speicher, Prozesse, Systemaufrufe, Formen, Kanäle, Datei-Dialog, Vorschau, Mikrofon, Ton, Not-Halt |
kernel/fs (SOFTrobotsFS + DB) | 6 949 | ≈ 152 KiB | Dateisystem, Datenbank, Joins, Serien, Snapshots, Versiegelung |
kernel/crypto | 4 865 | ≈ 106 KiB | SHA-2, HMAC/HKDF, AES-GCM, ChaCha20-Poly1305, X25519, Ed25519, ECDSA, RSA, X.509, TLS 1.3, DoH, NTS, Argon2id |
kernel/arch/aarch64 | 3 388 | ≈ 74 KiB | MMU, Exceptions, Interrupts, SMP, Timer; Swift 2 026 + Assembler 1 362 |
kernel/lib | 3 545 | ≈ 77 KiB | hardwareunabhängig, auf dem Mac getestet (Dateitypen, Manifest, Seitentabellen …) |
drivers/ | 2 631 | ≈ 57 KiB | NVMe, virtio (gpu, console, net, fs, sound, rng …), GICv3, PCIe, PL011, Framebuffer |
kernel/net | 2 457 | ≈ 54 KiB | IPv6/IPv4, TCP (mit 4 großen Empfangsringen), UDP, DHCP mit Erneuerung, DNS, mDNS |
| Summe Kernel + Treiber | 38 759 | 845 KiB |
Programme und Dienste (build/apps/*.elf, Build vom 10.11.2026)
Gemessen mit llvm-size. „Code“ enthält Konstanten; „Daten“ sind vor allem die eingebetteten UI-Schriften (rund 0,85 MiB je Programm mit Oberfläche).
Programmcode wird von allen Starts geteilt, nur die schreibbaren Daten werden je Start kopiert. Neu: chooser, der Öffnen-/Sichern-Dialog des Systems.
Der Code der meisten Programme ist kleiner als am 09.11. (z. B. web 1 129 → 1 041 KiB, files 885 → 824 KiB); Schätzung der Grund: seit 10.11. werden Programme mit Heap ohne Strict Alignment gebaut, nicht ausgerichtete Zugriffe werden nicht mehr in Einzelbytes zerlegt (Abschnitt 6.12) – nicht einzeln gemessen.
| Programm | Art | Code | Daten | BSS (RAM) | ELF-Datei |
|---|---|---|---|---|---|
| web | System | 1 041 KiB | 4 181 KiB | 1 668 KiB | 5 787 KiB |
| files | System | 824 KiB | 3 663 KiB | 1 292 KiB | 4 944 KiB |
| image | System | 524 KiB | 3 030 KiB | 1 241 KiB | 3 915 KiB |
| develop | System | 1 263 KiB | 1 899 KiB | 1 246 KiB | 3 864 KiB |
| reader | System | 385 KiB | 2 965 KiB | 1 241 KiB | 3 677 KiB |
| benchmark | System | 1 077 KiB | 1 886 KiB | 2 285 KiB | 3 599 KiB |
| display | Dienst | 641 KiB | 1 685 KiB | 1 349 KiB | 2 773 KiB |
| video | System | 773 KiB | 1 573 KiB | 1 246 KiB | 2 698 KiB |
| ask | System | 163 KiB | 1 668 KiB | 1 667 KiB | 2 039 KiB |
| about | System | 103 KiB | 1 591 KiB | 1 241 KiB | 1 881 KiB |
| server | System | 352 KiB | 1 096 KiB | 3 623 KiB | 1 741 KiB |
| watchdog | System | 156 KiB | 887 KiB | 1 666 KiB | 1 249 KiB |
| sound | System | 188 KiB | 845 KiB | 1 242 KiB | 1 228 KiB |
| database | System | 159 KiB | 855 KiB | 2 269 KiB | 1 188 KiB |
| activity | System | 134 KiB | 851 KiB | 1 241 KiB | 1 172 KiB |
| settings | System | 119 KiB | 863 KiB | 1 241 KiB | 1 155 KiB |
| console | System | 114 KiB | 849 KiB | 1 419 KiB | 1 127 KiB |
| chooser | System | 83 KiB | 841 KiB | 1 239 KiB | 1 094 KiB |
| monitor | System | 59 KiB | 838 KiB | 1 281 KiB | 1 032 KiB |
| text | System | 45 KiB | 841 KiB | 1 239 KiB | 1 028 KiB |
| timesync | Dienst | 90 KiB | 146 KiB | 1 668 KiB | 371 KiB |
| usbinput | Dienst | 26 KiB | 30 KiB | 0 KiB | 158 KiB |
| actuators | Dienst | 23 KiB | 3 KiB | 1 239 KiB | 77 KiB |
| canbus | Dienst | 8 KiB | 0 KiB | 0 KiB | 54 KiB |
6Kernkomponenten
6.1 Boot, EFI-Loader, Updates A/B und Rückfall
Wie es funktioniert: Die UEFI-Firmware startet \EFI\BOOT\BOOTAA64.EFI. Der Loader liest den Boot-Record (512 Bytes, zwei Kopien mit Folgenummer und CRC-32C in den reservierten FAT32-Sektoren 16/17),
wählt Systemkopie A oder B, lädt KERNEL_A.ELF bzw. KERNEL_B.ELF an seine feste physische Adresse, sammelt Speicherkarte, ACPI-RSDP und GOP-Framebuffer in der BootInfo (128 Bytes) und springt nach
ExitBootServices in den Kernel. entry.S wechselt falls nötig von EL2 nach EL1, baut frühe 16-KiB-Seitentabellen, schaltet die MMU ein und ruft kernelMain.
- Schnell: Messungen und Selbsttests laufen erst nach „Hello“; nichts auf dem Boot-Weg wartet auf das Netz.
make test-vmscheitert, wenn „Hello“ später als 1,0 s kommt. - Updates: Ein signiertes Paket (
.srupdate, Ed25519, Kernel + Systemvolume) wird in die inaktive Kopie geschrieben und beim nächsten Start ausprobiert; erreicht dieser „Hello“, bleibt sie. - Rückfall: Startet die neue Kopie dreimal nicht bis „Hello“, nimmt der Loader von selbst wieder die alte. Ein zurückgerollter Start zeigt Textzeilen statt Animation.
- Sicherheit: Systemvolume nur lesbar; Pakete mit falscher Signatur werden abgelehnt (
make test-update). Die Prüfung der Kernel-Signatur im Loader ist vorbereitet (Loader und Kernel sind getrennte Dateien), aber noch nicht gebaut. - Vorschau mit Ablaufdatum (10.11.2026,
docs/decisions.md):make previewbaut das Produktabbild ohne Testprogramme, ohne Entwicklungsschlüssel und ohne API-Schlüssel, mitmkimage --expires(Vorgabe 25.02.2027, Datei/expiresauf dem schreibgeschützten Systemvolume). Jeder Start schreibt die verbleibenden Tage ins Log; ab dem Ablauftag startet kein Programm, und der Bildschirm sagt, wo die neue Vorschau liegt (kernel/core/Preview.swift). Das 8-GiB-Abbild wird komprimiert ausgeliefert und beim ersten Start mit Löchern entpackt (≈ 100 MB auf der Platte); SOFTrobotsVM findet es neben sich. Signiert mit der Developer ID und von Apple notarisiert (seit 11.11.2026).make test-previewprüft beide Fälle in QEMU.
6.2 Scheduler
Wie es funktioniert: Ein Scheduler je Kern (bis 8 CPUs, 64 Kernel-Threads), tickless (ARM Generic Timer im One-Shot-Betrieb) und voll präemptiv. Drei Klassen:
| Klasse | Verfahren | Eigenschaften |
|---|---|---|
| Realtime | EDF mit Budget je Periode und Zulassungsprüfung | Periode 100 µs … 1 s; Auslastung je Kern höchstens 900 ‰; passt ein Vertrag nicht, startet das Programm gar nicht |
| Interactive | feste Prioritäten | Desktop, Dienste, normale Programme; Prioritätsvererbung in Volume-Sperre und IPC |
| Background | Fair Share nach Gewichten | Gewichte 2:1 ergeben gemessen genau 2,0 |
- Lastverteilung: Ein voller Kern gibt höchstens alle 10 ms einen wartenden Thread an einen leeren Kern ab (nie den laufenden, nie Echtzeit-Threads, nie den Echtzeitkern). Der alte Kern schiebt, weil nur er die Gleitkomma-Register des Programms sichern kann (Lazy FP/SIMD).
- Echtzeitkern: Die letzte CPU nimmt Echtzeit-Threads auf, andere Threads meiden sie. Mit zugelassener Echtzeit-Arbeit schläft sie nicht (kein
wfi), weil das Wecken einer virtuellen CPU rund 170 µs kostete. - Watchdog: Prüft alle 50 ms die Echtzeit-Programme und wendet die Reaktion aus dem Manifest an:
log,stop,restartoderstop-actuators. - Interrupts: GICv3 mit Prioritäten, kurze obere Hälften, Arbeit in Threads; MSI/MSI-X über das ITS.
6.3 Speicher
- 16-KiB-Seiten (der Kernel verlangt das 16-KiB-Granule), 32-MiB-Blöcke für große Puffer, Buddy-Allokator für physische Seiten, bis 16 GiB verwalteter RAM, 48-Bit-Adressen.
- W^X überall: kein ausführbarer Datenbereich, kein schreibbarer Code – im Kernel und in jedem Programm. Direct Map für den Kernel, Geräte nur über
MMU.map. - Ein Adressraum je Programm (EL0): Code ab
0x1000_0000, Heap darüber, Stack mit Guard Page, Kanalseiten, Geräte- und DMA-Fenster nur für Treiberdienste. - Kein Kernel-Heap (
-no-allocations); Programme im Echtzeitprofil haben gar keinen Heap. - Zusagen statt Swap:
memory =im Manifest (16–2048 MiB, Vorgabe 256 MiB) ist eine Zusage, die beim Start zugelassen und nie weggenommen wird. Darüber gibt es Leihe aus freiem RAM. 256 MiB Systemreserve (Not-Halt, Echtzeit, Dienste) werden nie verliehen. - Spitzen-Polster: ca. 3 % des RAM (64 MiB … 1 GiB), sofort auf Anfrage für Spitzen, höchstens die Hälfte je Programm, sichtbar in Activity und auf dem Desktop.
- Eigener Auslagerungsbereich (Stufe 2): zurückgeforderte Leihseiten gehen nur in den Bereich dieses Programms (2 × Zusage, höchstens 4 GiB), AES-GCM je Seite mit einem Schlüssel nur für diesen Lauf. Ein Programm über seiner Zusage wird langsamer – kein anderes. Echtzeit-Programme werden nie ausgelagert.
6.4 IPC – Kommunikation zwischen Programmen
- Kanal = eine gemeinsame Seite mit zwei Nachrichtenringen (Single-Producer/Single-Consumer, Nachrichten bis 256 Bytes) zwischen genau zwei Programmen, gefunden über den Namen. Der Kernel kopiert nie eine Nachricht – er bildet die Seite ab und weckt die Gegenseite.
- 16 Kanäle im System (am 08.11.2026 von 8 angehoben). Dazu Veröffentlichungen/Abos (16 Plätze), Aufnahme-Ringe für Serien und Erkennungs-Ringe von Video.
- Systemaufrufe: 13 Grundbefehle (0–12: exit, yield, sleep, wait, periodWait, memoryGrow, workerWake, workerExit, channelNotify, channelWait, deviceWait, surfaceNotify, inputReceive), die nur warten, wecken oder enden und rund 100 ns kosten sollen.
Alles, was mit einem Objekt arbeitet, geht über den Formaufruf 13 (24 Module, 138 Aufrufe, 222 Formen und 29 Aufzählungen in 23 Dateien
shapes/*.shape, gezählt am 10.11.2026; neu ist das Moduldialog0x0013). Obergrenze: 100 Systemaufrufe. - Gemessen: Nachricht hin und zurück zwischen zwei Programmen auf verschiedenen Kernen 1,5 µs (bester Durchgang 1,4 µs), auf demselben Kern 8,4 µs (dort muss der Prozessor wechseln). Wartet die Gegenseite gerade aktiv, entfällt der Weck-Aufruf ganz (Merkzeichen im Ring, F143). Ziel < 1 µs: in der VM noch nicht ganz erreicht. Am 08.11.2026 behoben: kopierte Tabellen im Scheduler (F142) und Schlafen nach 2 µs Warten (F143) – vorher 14,5 µs.
6.5 Sicherheitsmodell
| Schutz | Umsetzung |
|---|---|
| Nur signierte Programme | Jedes Programm und sein Manifest sind mit Ed25519 signiert; unsignierte oder veränderte Programme startet der Kernel nicht (Testprogramme unsigned, tampered). Auch Updates und KI-Modelle sind signiert. |
| Capabilities | 32 Rechte (Bits 0–31 von 64; neu am 10.11. files.dialog, nur für chooser) aus dem signierten Manifest, z. B. network.outgoing, network.incoming, files.own, safety.stop, device.can, device.microphone. Jeder Aufruf wird geprüft. Ohne network.incoming keine eingehenden Verbindungen; lauschen darf nur Server auf den Ports seines Manifests. |
| Eigener Ordner | Mit files.own existiert für ein Programm nur /data/<name>; . und .. gibt es nicht. Echtzeit-Programme haben keinen Dateizugriff. |
| Datei-Dialog: Wählen ist Erlauben (10.11.2026) | Ein Programm fragt mit Dialog.open oder Dialog.save; den Dialog zeigt das System-Programm chooser, nicht das fragende Programm. Der Kernel prüft Ort, Typ und Inhalt der Wahl und gibt eine Freigabe für genau diese Datei – ohne Dateirecht im Manifest, bis 16 je Programm, solange es läuft; ein „Zuletzt benutzt“ gibt es nicht.
Orte: der eigene Ordner, der gemeinsame Ordner /documents und in SOFTrobotsVM der Mac-Ordner; fremde Programmordner, System und Logs nie. Jede Frage hat eine Nummer und gehört einem Programm; bis 3 Dialoge gleichzeitig. Geprüft mit make test-dialog (PASS nach 8 s, Hb. 3.135). |
| Programm-Identität | Jedes Programm hat eine Kennung (id =, Reverse-Domain) und Version im signierten Manifest; der Ordner ist an die Kennung gebunden. In Develop gebaute Programme werden mit dem Schlüssel dieses Roboters signiert und laufen nur hier. |
| Geräteschutz | Argon2id (64 MiB, 3 Durchläufe) aus dem Passwort entschlüsselt den zufälligen Volume-Schlüssel; DATA ist mit AES-256-GCM je Block versiegelt. Das Passwort wird nie gespeichert. Einmaliger Wiederherstellungsschlüssel (128 Bit), Bildschirmsperre, Fehlversuche verzögern 2–60 s. |
| Prozessor-Schutz | W^X, PAN (Kernel liest Programmspeicher nicht aus Versehen), PAC (Rücksprungadressen signiert), BTI (Sprungziele markiert), Stack-Canaries, Guard Pages – geprüft durch make test-fault (6 Fälle). |
| Isolierte Treiber | USB und Grafik laufen als EL0-Dienste. Grenze: Ohne SMMU (Virtualization.framework hat keine) ist ein Treiberdienst nur von der CPU-Seite isoliert; sein Gerät könnte per DMA auf fremden Speicher zugreifen. |
6.6 Netzwerk
- Eigener Stack in Swift im Kernel: IPv6 zuerst (SLAAC), IPv4 (DHCP), TCP mit SACK, CUBIC und Window Scaling, UDP, DNS, mDNS (
<name>.localim Heimnetz). Interrupts statt Polling; 64 TCP-Verbindungen im System. - Nur TLS 1.3 (X25519, AES-GCM, ChaCha20-Poly1305), als Client und als Server. Namensauflösung nur über DNS über HTTPS, Uhrzeit über NTS (authentifiziertes NTP).
- Server – das einzige Tor nach drinnen: nur Tür 443 (alles hinter dem Login) und Tür 80 (Umleitung), kein öffentlicher Webserver. Eigene Stammstelle des Roboters (ECDSA P-256), Zugang per Einladung mit Code und Koppeln des Geräts, 5 falsche Passwörter in 10 Minuten sperren die Adresse 15 Minuten. Von unterwegs über das VPN des Heimrouters.
- Keine konfigurierbare Firewall nötig: Ein Port ohne Lauscher antwortet gar nicht.
- Gemessen: TLS-1.3-Handshake 79,7 ms, Namensauflösung über DoH 115 ms (Benchmark 08.11.);
Ping zum Gateway 0,1 ms (Boot-Log 08.11.); HTTPS-Download 5 MB mit Window Scaling 42 Mbit/s (SOFTrobotsVM, 29.10.2026,
docs/handbuch/daten/tcp-durchsatz.txt; Grenze ist die Arbeit je Paket in der App). - Am 09.11.2026 behoben (F146): Downloads brachen nach 1–7 MB ab. Ursache:
net.receivefüllte den 1-KiB-Puffer in Teilstücken und das zweite Stück durfte zu viel holen; dazu TCP nach einem Timeout und TLS-KeyUpdate. Neue Tests: ein nachgebauter Sender schickt beliebige gültige Stücke, 2 MB kommen exakt an; Verlust, Verdopplung und Vertauschung werden überstanden. Web setzt abgebrochene Downloads mit einem Range-Request fort (höchstens dreimal). - Schnellere Downloads (10.11.2026,
docs/benchmarks/network-download.md, Hb. 3.137): Eine Verbindung, die mehr als 1 MiB empfangen hat, bekommt einen von 4 Empfangsringen zu 1 MiB; ihr TCP-Fenster ist dann 1 MiB statt 128 KiB, die Fensterskalierung steht auf 4 statt 3 (kernel/net/TCP.swift). Gemessen: 57 MB (Big Buck Bunny, 360p-WebM von Wikimedia) in 4,1 s = 13,6 MB/s statt etwa 2,7 MB/s (SOFTrobotsVM auf dem M3 Pro, Mac im WLAN, Laufzeit zu Wikimedia ≈ 35 ms). Grenze durch das Fenster: 128 KiB / 35 ms ≈ 3,7 MB/s, 1 MiB / 35 ms ≈ 30 MB/s; darüber begrenzen WLAN, Server oder die TLS-Entschlüsselung in Web (ChaCha20-Poly1305 82 MB/s im Selbsttest des Kernels). Web schreibt Dauer und Tempo jedes Downloads ins Log. - Netz-Diagnose (F149, Hb. 3.136): DHCP erneuert die IPv4-Adresse bei der Hälfte der Laufzeit (vorher lief sie in SOFTrobotsVM nach einer Stunde ab); DNS-Fragen ohne Antwort stehen mit dem Zustand des Routers im Log; Buddy bellt, wenn das Internet nicht erreichbar ist (Regel 13).
6.7 Grafik und Anzeige
- Nur 2D: GOP-Framebuffer oder virtio-gpu 2D, Zeichnen auf der CPU. Keine 3D-Grafik, keine Vollbild-Effekte (kein Abdunkeln, keine Schatten).
- Fenstersystem als EL0-Dienst (
display): Programme zeichnen nur in ihre eigene Zeichenfläche; der Dienst setzt zusammen, zeichnet nur geänderte Bereiche, doppelt gepuffert. Ein Bildzähler je Fenster verhindert halb gezeichnete Bilder. - 16 Zeichenflächen im System, 3 je Programm; Titel kommen aus dem signierten Manifest, damit sich kein Programm als ein anderes ausgeben kann.
- Hell und Dunkel, Maßstab 2 ab 2400 × 1500. Alle Decoder und Encoder für Bilder, Dokumente, Video und Ton laufen in der Programm-Laufzeit (nie im Kernel) – die vollständige Liste steht in Abschnitt 9.
- Fensterknöpfe (10.11.2026, Hb. 3.137): rechts im Titel [Ablegen] und [×], immer sichtbar; die Kapseln für Fortschritt und Speicher stehen ohne Lücke daneben. Das × wird in drei Schritten rot. Keine Animation (Inhaber).
- Laschen im Dock: Ein abgelegtes Fenster ragt als kleines bernsteinfarbenes Fenster aus der Kachel seines Programms (höchstens 3 gestapelt); ist kein Fenster des Programms sichtbar, wird der Punkt unter der Kachel zum Ring. Neu im Manifest:
dock = no– das Programm erscheint nie im Dock (genutzt von chooser). - Fortschritt für alle Programme (Hb. 3.136): ein Aufruf
surface.progress(…)(userland/ui/Progress.swift); das System zeichnet eine Kapsel im Fenstertitel (Balken, Prozent, Restzeit) und einen dünnen Balken auf der Dock-Kachel. Abbrechen nur, wenn das Programm es anbietet – als Bit in der Ringseite des Fensters, das auch ein Programm in einer Schleife sieht. Buddy meldet eine Aufgabe von mindestens 3 s, die endet, während ihr Fenster nicht vorne ist. Erster Nutzer: Web. - Speicherfenster (Hb. 3.136): Ein Klick auf die Speicheranzeige im Titel zeigt den Verlauf der letzten 10 Minuten (ein Punkt alle 2 s, für jedes Programm immer aufgezeichnet), Heap-Spitze, Garantie, Nutzung des Polsters und einen Vorschlag für
memory =(apps/display/MemoryCard.swift). - Einheitliches File-Menü (Hb. 3.135): Programme mit Dateien bekommen es vom System (
surface.addFileMenu): New ⌘N, Open… ⌘O, Save ⌘S, Save As… ⇧⌘S, Export… ⌘E, Show in Files; Menüleiste „Programm · File · Edit · …“.
6.8 USB mit Erlaubnisliste
XHCI-Treiber als EL0-Dienst usbinput. Konzept: Erlaubt sind HID, CDC-ACM (seriell), UVC (Kameras) und herstellerspezifische Schnittstellen nur mit signiertem Treiberdienst.
Jede andere Schnittstelle führt dazu, dass das ganze Gerät abgelehnt wird. Heute gebaut: HID (Tastatur, Zeiger) mit Interrupts; CDC-ACM und UVC folgen mit echten Geräten.
6.9 Sicherheit am Roboter: Not-Halt
- Not-Halt im Kernel (
Safety): stoppt alle Aktoren sofort, auch während der Start-Animation (⌘+Esc), über den immer sichtbaren Knopf in der Menüleiste oder die Statusseite von Server. Lösen nur am Roboter. - Programme kommen nie direkt an Motor oder Bus: Der Aktor-Dienst begrenzt jede Bewegung (heute im Code: −90…+90°, 30°/s) bevor ein Befehl auf den CAN-FD-Bus geht.
- Gemessen: Not-Halt bis gesendeter Stopp-Rahmen 10–12 µs (SOFTrobotsVM, Handbuch Kapitel 6). Der Flugschreiber sichert bei Not-Halt oder Absturz die letzten Sekunden der Aufzeichnung.
6.10 Ton und Mikrofon
- Ausgabe: virtio-sound, 48 kHz, 16 Bit, Stereo, Abschnitte von 10 ms. Mischer im Kernel: jedes Programm mit
sound.playbekommt einen Ring von etwa 341 ms; das Gerät startet mit dem ersten Ton und stoppt nach einer Sekunde Stille (Hb. 3.100). - Mikrofon (09.11.2026, Hb. 3.134): virtio-sound-Eingang, läuft nur, solange ein Programm zuhört. Ein Ring je Mikrofon (48 kHz, 16 Bit, ≈ 1,4 s), schreibgeschützt in jedes zuhörende Programm eingeblendet, mit Pegel (Spitze und RMS) alle 10 ms. Recht
device.microphone. - Immer sichtbar: rote Pille „MIC · Programm“ in der Menüleiste, nicht versteckbar; „Stop the microphone“ stoppt alle Zuhörer. Settings › Privacy zeigt, wer die Kamera sieht und wer das Mikrofon hört.
- Sound (10.11.2026): Menüs „Sound, File, Edit“; Open… und Save As… (FLAC oder WAV) über den System-Dialog.
6.11 Formen, Reflex und Develop
- Alles ist eine Form:
.shape-Dateien beschreiben einmal, was API, Kernel-Prüfcode (nur Ganzzahlen, kein Heap), Datenbanktabellen, Ringe und Netz verwenden. Stabile Layouts: veröffentlichte Felder behalten ihren Platz. - Reflex: eigene Sprache mit Lexer, Parser, Ein-Pass-Compiler zu Bytecode und einer Maschine; jede Zeile nennt ihr Modul, daraus ergeben sich die Rechte des Skripts.
- Develop: prüft bei jeder Änderung (übersetzen und Tests), Simulate erfindet Ereignisse, „Fast“ übersetzt zu ARM64-Maschinencode. „Save as Program“ legt ein signiertes Programm an – nie mit schreibbarem Code.
- Beweisbare Echtzeit: Für
realtime every 1 mszählt der Compiler die schlechtesten Takte jeder Anweisung (jeder Speicherzugriff als Cache-Fehlgriff, bei nur 1 GHz) und startet nur, wenn höchstens 80 % der Periode gebraucht werden.
6.12 Video-Wiedergabe: Schritt für Schritt gemessen (10.11.2026)
Regel des Inhabers: erst messen, dann je eine Änderung, wieder messen; was nichts bringt, fliegt wieder raus. Video schreibt je Wiedergabe eine Zeile in /data/video/measurements.csv und jede Sekunde eine Logzeile
(gezeigt, verspätet, übersprungen, Dekodier-, Umrechen- und Zeichenzeit; apps/video/PlayStats.swift). Mac-Werte kommen aus dem Host-Test vp9FileSpeed, VM-Werte aus make vm-vp9-bench (600 Bilder Big Buck Bunny 1080p). Quelle aller Zahlen: docs/benchmarks/video-playback.md.
| Schritt | Was sich änderte | Gemessen | Behalten? |
|---|---|---|---|
| 1 Ausgangspunkt | Ein Bild wird erst dekodiert, wenn es fällig ist; Rückstand führt zurück zum Schlüsselbild; feste Wartezeit 15 ms | VM, 360p mit 60 Bildern/s: 3–14 von 60 gezeigt, 51–73 übersprungen je s | Referenz |
| 2 Vordekodieren | bis 4 Bilder voraus dekodiert und umgerechnet; bei Rückstand der Reihe nach dekodiert, nicht gezeigt (der Ton läuft weiter) | VM, 360p: 60–61 von 60, 0 übersprungen, höchstens 3 ms zu spät; je Bild ≈ 6 ms (dekodieren 2,2–3,4, umrechnen 0,6, zeichnen 2,2 ms) | ja |
| 3 Farbumrechnung mit SIMD | YUV→RGB vektorisiert, bytegleich mit der einfachen Formel | Mac, 1080p: 3,14 → 1,12 ms je Bild (2,8×) | ja |
| 4 „für Tempo bauen“ | entfiel: Video war schon mit -O gebaut | – | – |
| 5 Aufholen in Schritten | beim Aufholen höchstens 4 Bilder am Stück, damit das Bild weiterläuft | VM, 1080p im Rückstand: 11–20 statt 1–4 Bilder je s | ja |
| 6 Schleifenfilter über rohe Zeiger, auf 3 Kernen | Superblock-Zeilen parallel auf Hauptthread und zwei Workern; bitgleich mit einem Thread | Mac, 1080p: 6,00 → 3,34 ms je Bild | ja |
| 7 Schleifenfilter mit SIMD (8 Abtastwerte auf einmal) | bitgenau gebaut; die meisten Kanten scheitern am ersten Test, wo der einfache Filter sofort zurückkehrt | Mac, 1 Thread: 6,90 → 7,92 / 7,71 ms (12–15 % langsamer) | entfernt |
| 8 Bewegungsausgleich (8-Tap-Filter) mit SIMD | vermutlich hatte der Compiler die Schleife schon vektorisiert | Mac, 1 Thread: 6,90 / 7,16 → 6,96 / 7,07 ms, kein Unterschied | entfernt |
| 9 Ohne Strict Alignment, -O für uses-video | siehe Kasten unten | VM, 1080p, 3 Threads: 13,0 → 8,9 ms; umrechnen 4,3 → 1,4 ms | ja |
| 1080p, je Bild | VM vorher | ohne Strict Alignment | + -O für uses-video | Mac |
|---|---|---|---|---|
| dekodieren, 1 Thread | 15,5 ms | 13,7 ms | 10,5 ms | 6,9 ms |
| dekodieren, 3 Threads | 13,0 ms | 11,2 ms | 8,9 ms | 3,3 ms |
| YUV → RGB umrechnen | 4,3 ms | 1,5 ms | 1,4 ms | 1,1 ms |
Umrechnen in einen gehaltenen Puffer: 1,1 ms (ein frischer 8-MB-Puffer je Bild kostete etwa 1 ms in neuen Seiten). Dekodieren und Umrechnen brauchen damit in der VM etwa 10 ms der 16,7 ms, die ein Bild bei 60 Bildern/s haben darf. 720p lief schon nach Schritt 5 mit 60 von 60. Ton: Lief der Tonring (200 ms voraus) während eines Hängers leer, verschob sich der Ton; jetzt springt er zur Bildzeit („sound resynced n“ im Log). Offen: warum drei Threads in der VM nur 16–20 % bringen, auf dem Mac 50 %.
docs/decisions.md, 10.11.2026): Die VM dekodierte denselben Code 2- bis 4-mal langsamer als der Mac. Eine reine Rechenschleife braucht in VM und auf dem Mac gleich lang (249 / 248 ms) – die Kerne der VM sind nicht langsamer.
Ursache: Alle Programme wurden mit -Xcc -mno-unaligned-access gebaut (vom Kernel geerbt, der anfangs ohne MMU läuft); Swift zerlegte damit jeden nicht ausgerichteten 8-Byte-Zugriff in Einzelbytes (in der Disassemblierung von rgba: ldrb/orr, strb).
Jetzt behalten nur Programme ohne Heap die Einstellung (sie dürfen Geräteregister einblenden: usbinput, canbus); Programme mit Heap sehen nur normalen Speicher, wo nicht ausgerichtete Zugriffe erlaubt sind. Programme mit uses-video werden wie uses-infer mit -O gebaut; jedes Programm mit Heap wurde neu gebaut.7Dateisystem SOFTrobotsFS
Aufbau
- Copy-on-Write: nie wird ein gültiger Block überschrieben; ein Commit schreibt neue Knoten und schaltet dann einen einzigen Wurzelzeiger im doppelten Superblock um. Kein Journal.
- B+-Bäume für Objekte und Extents; Schlüssel (Objekt, Typ, Offset) halten alles eines Objekts beisammen; bis 8 Ebenen.
- 16-KiB-Blöcke = Seitengröße = Baumknoten: Cache-Rahmen gehen ohne Umkopieren an die NVMe.
- CRC-32C (Prozessorbefehl) auf allen Daten und Metadaten.
- AES-256-GCM je Block (versiegeltes Volume): Kopf als zusätzliche Daten, Tag und Nonce im Kopf; Eltern speichern die Generation jedes Kindes – ein alter Block kann nicht unbemerkt zurückgespielt werden.
- Snapshots alle 15 Minuten, Aufbewahrung 24 h / 7 Tage / 30 Tage, höchstens 400; der Zeitregler in Files und Database zeigt alte Stände.
- Kleine Dateien bis 2 KiB direkt im Baum (kein eigener Datenblock), Ordnersummen sofort, kein atime.
- Freiplatz-Karte auf der Platte (Volume bis ≈ 1,99 TiB), 32-MiB-Hash-Cache, gebündelter Commit mit FUA, bis 32 Schreibbefehle gleichzeitig.
- Geplant: gebündeltes TRIM (noch nicht gebaut).
Warum es schnell ist
- Kein Journal: jede Änderung wird einmal geschrieben, nicht zweimal.
- Block = Seite = Knoten: kein Umrechnen, DMA direkt aus dem Cache.
- Prüfsumme und Verschlüsselung in Hardware: AES-256-GCM 3197 MB/s versiegeln, 2945 MB/s öffnen.
- Kein atime: Lesen erzeugt keine Schreibzugriffe; kleine Dateien kosten keinen Extra-Block.
- Im Kernel, ohne POSIX-Schichten dazwischen.
Vorteile
- Stromausfall: immer genau der alte oder der neue Stand, nie etwas dazwischen (Host-Tests mit vertauschter Schreibreihenfolge bei jedem Schreibvorgang).
- Jede stille Beschädigung wird erkannt; ein versiegeltes Volume ist ohne Passwort unlesbar und manipulationssicher.
- Snapshots kosten fast nichts – sie sind eine Folge von Copy-on-Write.
Gemessen (Kernel, 4 MiB)
Schreiben + Commit 204 MB/s · Lesen + CRC-Prüfung 521 MB/s
Am 28.10. nach den ersten Optimierungen: 41,0 → 203,2 MB/s schreiben, 198,5 → 518,7 MB/s lesen (Handbuch Kapitel 6). Der Wert schwankt mit dem Datei-Cache des Macs (01.11.: 166 / 389 MB/s, Hb. 3.58).
Messwerte des Dateisystems im Einzelnen
| Messung | Wert | Wo / wie gemessen |
|---|---|---|
| NVMe: ein 16-KiB-Befehl lesen / schreiben | 50,3 µs / 97,6 µs | Kernel beim Start, Boot-Log 08.11.2026 |
| NVMe sequentiell (256 KiB, 16 Befehle gleichzeitig) lesen / schreiben | 1073 MB/s / 443 MB/s | Kernel beim Start; die VM-Platte ist eine Datei auf dem Mac |
| Commit einer neuen Datei | 3,3 ms | Boot-Log 08.11.; fast ganz der Flush der VM-Platte |
| Commit von 280 neuen Dateien in einem Zug | 4,2 ms | 13 Knoten gemeinsam an die NVMe, ohne Umkopieren („0 bounced since the boot“), Boot-Log 08.11. |
| DATA einbinden (versiegelt, über die Freiplatz-Karte) | 11 ms | nur Superblöcke und Kartenblöcke gelesen (Hb. 3.58, 01.11.2026) |
| Prüfung aller Knoten nach „Hello“ (403 Blöcke) | 7,1 ms | 0 Schäden, 0 fehlende Kartenbits (Hb. 3.58); läuft im Diagnose-Thread, bremst den Boot nicht |
| Knoten-Cache beim Start: Treffer / Lesezugriffe | 1087 / 12 · 289 / 1 | Systemvolume · DATA, Boot-Log 08.11. |
| Programm: 4-MiB-Datei schreiben / lesen | 113 MB/s / 239 MB/s | Benchmark, über die Systemaufrufe (16 KiB je Aufruf) |
| Kleine Datei anlegen und löschen | 8,9 ms | Benchmark |
| Ordnereintrag auflisten | 394 µs | Benchmark |
| Plattenverschlüsselung AES-256-GCM versiegeln / öffnen | 3197 MB/s / 2945 MB/s | Kernel beim Start, bitgleich zur Software-Referenz, Manipulation erkannt |
8Datenbank SOFTrobotsDB
Eine Datenbank ist keine Datei mit eigenen Seiten, sondern ein eigenes Objekt im Dateisystem (Art „database“ neben Datei und Ordner) mit einem eigenen Copy-on-Write-B+-Baum – aus denselben 16-KiB-Knoten, mit derselben Blockverwaltung,
derselben Prüfsumme bzw. Verschlüsselung und demselben Commit. Der Commit des Dateisystems ist der Commit der Datenbank; es gibt kein Write-Ahead-Log und keine zweite Kopierschicht
(docs/database-concept.md, Abschnitt 1; Code in kernel/fs/softrobotsfs/Database.swift, Tables.swift, Query.swift, Schema.swift).
8.1 Funktionen
- Tabellen als gespeicherte Formen: Typen bool, int8–64, uint8–64, float32/64, text(n), bytes(n), time, enum, id, ref, file; Regeln optional, unique, default, range.
- Der Kernel prüft jede Zeile (Pflichtfelder, Größe, gültiges UTF-8, Bereiche auch für Gleitkomma, NaN abgelehnt, unique, ref, file) – eine fehlerhafte App kann keinen Unsinn speichern.
- Indexe (16 je Tabelle, 8 Felder je Index) im selben Schreibpaket wie die Zeile; Abfragen mit Filtern (64 Knoten), Sortierung über bis zu 4 Felder, Top-N, Gruppen, Summe/Durchschnitt (128 Bit intern), Cursor; „explain“ nennt den Plan.
- Joins über ref-Felder (09.11.2026, Hb. 3.128): bis zu zwei Joins für WHERE und ORDER BY, bis zu vier zum Anzeigen; der Kernel liest die verknüpfte Zeile selbst (eine Punktabfrage je Zeile und Join). Noch nicht: GROUP BY über verknüpfte Felder, Index über verknüpfte Felder.
- SQL (nur lesend) in Console und Database; die Übersetzung in den festen Bauplan läuft im Programm, der Kernel versteht keine Textsprache.
- Schema ändern (Feld hinzufügen, entfernen, umbenennen, Enum erweitern): sofort, ohne eine Zeile umzuschreiben.
- Serien, Aufnahme-Ringe und Flugschreiber (die letzten Sekunden, gesichert bei Not-Halt oder Absturz).
8.2 Gemessen (Benchmark 08.11.2026, über die Systemaufrufe aus einem Programm)
| 1000 Zeilen einfügen, auf die Platte gewartet | 22,2 ms |
| 1000 Zeilen „soon“ (dauerhaft binnen 10 ms) | 10,3 ms |
| Eine Zeile nach Id | 30,4 µs |
| Bereich über einen Index (100 Zeilen) | 5,2 ms |
| Top 100 von 1000 ohne Index sortiert | 29,0 ms |
| Zählen in Gruppen (1000 Zeilen) | 3,8 ms |
| SQL-Anweisung übersetzen | 3,5 µs |
| Messwerte in den Ring (Echtzeit-Weg) | 1,1 Mio./s |
| davon verworfen (10 000 geschrieben) | 0 |
| Zeitbereich zurücklesen (1000 Datensätze) | 14,2 ms |
Je Zeile: 22,2 µs dauerhaft, 10,3 µs mit „soon“. Erste Messung in Stufe 4 (01.11.2026, Testprogramm dbcheck, mit unique-Feld, zwei Indexen, Prüfung aller Regeln und Rücknahme-Protokoll): 17 ms bzw. 5,9 ms für 1000 Zeilen. Ein kleiner dauerhafter Schreibvorgang kostete 3,6 ms, fast ganz der Flush der VM-Platte (Hb. 3.62, 01.11.2026). Die erste Messung war 17-mal langsamer (291 ms für 1000 Zeilen, F80) – gefunden nur, weil eine echte App in der echten VM maß.
8.3 Grenzen
| Grenze | Wert | Grenze | Wert |
|---|---|---|---|
| Datensatz (alle Felder) | ≤ 4096 Bytes – große Daten als Datei (8.5) | Tabellen / Felder | 64 je Datenbank / 64 je Tabelle |
| Schlüssel | 1–255 Bytes | Schreibpaket (Transaktion) | ≤ 4 MiB, vorher vollständig geprüft |
| Baumtiefe | 8 Ebenen – bei 100-Byte-Zeilen weit über 10 Milliarden Zeilen | Zeilen je Abfrage-Aufruf | 256 (Ausgabe ≤ 256 KiB), weiter per Cursor |
| Sortieren ohne Index | Top-N ≤ 1000 | Gruppen | 256, Gruppenwert ≤ 32 Bytes |
| Offene Datenbanken | 4 je Programm, 32 im System | Serien-Datensatz | 8–1024 Bytes, Ring 1–600 s, ≤ 32 MiB |
8.4 Warum die Datenbank schnell ist – und um wie viel
| Grund | Was es bewirkt | Vorteil |
|---|---|---|
| Eine Schicht statt zwei | Kein Write-Ahead-Log, kein Journal, keine Datenbank-Datei in einem Dateisystem. Ein geänderter Knoten wird einmal geschrieben; der Wurzelwechsel im Superblock macht alles auf einmal gültig. | Schätzung etwa 2- bis 3-mal weniger Flushes je kleinem dauerhaftem Commit als „Datenbank-Datei mit eigenem Log auf einem Journal-Dateisystem“: ein Flush + FUA-Superblock statt Log-Flush plus Journal des Dateisystems (Konzept, Abschnitte 5.2 und 9). Auf Verbraucher-NVMe ist der Flush der teure Teil. |
| Gebündelter Commit (Group Commit) | Schreibvorgänge vieler Programme, die während eines Commits ankommen, teilen sich den nächsten Flush; alle schmutzigen Knoten gehen zusammen an die NVMe (bis 32 gleichzeitig). | Schätzung unter Last ein Vielfaches an dauerhaften Commits je Sekunde, weil der Durchsatz mit der Last wächst statt an der Flush-Dauer zu hängen (Konzept 5.3: „tausende pro Sekunde“). |
| Ein Systemaufruf je Transaktion | Das Schreibpaket wird ohne Server-Prozess geprüft und in einem Zug angewandt; das Ergebnis kommt direkt in den Speicher des Programms. | gemessen: 10,3 ms für 1000 Zeilen in einem Aufruf |
| Abfragen im Kernel nahe an den Daten | Filter, Sortierung, Gruppen und Joins laufen dort, wo die Knoten im Cache liegen; über das Systemaufruf-Fenster wandert nur das Ergebnis. | gemessen: Zählen in Gruppen über 1000 Zeilen 3,8 ms |
| Ein Cache für alles | Der Block-Cache des Kernels (32 MiB, 2048 Plätze, Hash-Suche) hält Dateien und Datenbanken; seine 16-KiB-Rahmen sind zugleich Seiten und DMA-Puffer – kein Umkopieren, kein zweiter Cache im Programm. | innere Knoten bleiben im Cache: ein nicht zwischengespeicherter Zugriff kostet genau einen Plattenzugriff (Konzept 4) |
| Ringe für Messwerte | Ein Echtzeit-Thread schreibt ohne Systemaufruf und wartet nie; ist der Ring voll, wird verworfen und gezählt. | gemessen: 1,1 Mio./s, 0 verworfen. Qualitativ: aus einem Echtzeit-Thread ist das mit einer üblichen Datenbank gar nicht möglich. |
| Snapshots aus Copy-on-Write | Ein Snapshot der Datenbank ist ein Snapshot des Dateisystems. | kostet keine Kopie – statt einer vollständigen Sicherung |
Ehrlich: Bei einzelnen Punktabfragen ist SOFTrobotsDB nicht um ein Vielfaches schneller – die sind auf jeder Seite durch Speicher und Gerät begrenzt (Konzept, Abschnitt 9). Der Vorsprung liegt bei dauerhaften Commits, bei vielen Schreibern, bei Messwerten aus Echtzeit-Code und bei großen Daten (8.5).
8.5 Dateien als Feld: warum die Datenbank bei großen Daten nicht begrenzt ist
Ein Datensatz ist höchstens 4 KiB groß (Entscheidung des Inhabers, Konzept 15.5 Punkt 9). Bilder, Aufnahmen, Modelle oder Messdateien gehören deshalb nicht in die Zeile, sondern in das Dateisystem –
die Zeile verweist auf sie mit dem Feldtyp file (Konzept 15.6, Vorschlag des Inhabers vom 01.11.2026). Weil Datenbank und Dateien im selben Dateisystem liegen, ist das kein loser Pfad-Verweis wie bei einer Datenbank-Datei neben anderen Dateien, sondern ein Verweis innerhalb desselben Copy-on-Write-Baums.
Wie es funktioniert (aus dem Code)
- Ein
file-Feld speichert die Objektkennung der Datei in SOFTrobotsFS (8 Bytes,Schema.swift: feste Größe 8), keinen Pfad. Kennungen kommen aus einem Zähler im Superblock und werden nie wiederverwendet. - Beim Schreiben prüft der Kernel jede Zeile: das Objekt existiert, ist eine Datei und liegt im Ordner des Programms (
Tables.swift:info(of:)?.kind == .fileundisBelow(…, fileFieldRoot); den Ordner setztDatabaseAccess.swiftbeim Öffnen). Sonst wird die Zeile mit „not a file in the app's folder“ abgelehnt. - Umbenennen und Verschieben der Datei ändern die Kennung nicht – der Verweis bleibt gültig. Eine gelöschte Datei wird nicht blockiert; das Feld liest sich dann als „fehlt“ und kann nie auf eine neuere, andere Datei zeigen.
- Die Datei selbst ist eine ganz normale Datei: Extents bis 16 Blöcke = 256 KiB (versiegelt 4 = 64 KiB), jeder Block mit eigener Prüfsumme bzw. eigenem GCM-Tag, Eltern speichern die Generation jedes Kindes.
Warum das schneller ist – und warum
- Große Daten werden genau einmal geschrieben – in die Extents der Datei. Keine Überlauf-Seitenkette in der Datenbank, kein Log, das dieselben Bytes ein zweites Mal enthält. Schätzung etwa halb so viel Schreibvolumen wie ein großer Wert in einer Datenbank mit Write-Ahead-Log (dort: erst ins Log, später in die Datenbankseiten).
- Zeilen bleiben klein: Abfragen, Indexe, Sortieren und Joins berühren die Datei nie. Eine Zeile nach Id kostet 30,4 µs – unabhängig davon, ob die Datei 1 KB oder 1 GB groß ist. Schätzung Durchläufe über Tabellen mit großen Anhängen bleiben so schnell wie über Tabellen ohne, weil kein Knoten mit Anhang-Bytes gelesen wird.
- Lesen am Stück: Extents liegen zusammenhängend (bis 256 KiB); Cache-Rahmen sind zugleich DMA-Puffer, die NVMe liest ohne Zwischenpuffer („0 bounced“). Gemessen: Kernel 4 MiB lesen + CRC 521 MB/s, aus einem Programm 239 MB/s (16 KiB je Aufruf, also eine Kopie ins Programm – kein Zero-Copy bis in die App).
- Verschlüsselung kostet fast nichts: AES-256-GCM öffnet mit 2945 MB/s, fast dreimal so schnell, wie die VM-Platte sequentiell liest (1073 MB/s) – beide Werte im selben Start gemessen.
- Kopie und Sicherung umsonst: Ein Snapshot einer Tabelle mit tausend großen Dateien kopiert keine einzige Datei (Copy-on-Write).
| Teil des Datei-Felds | Stand | Wo / Bemerkung |
|---|---|---|
Feldtyp file im Kernel: 8-Byte-Objektkennung, Prüfung „existiert, ist Datei, im Ordner des Programms“ | gebaut | Stufe 2 (01.11.2026) und 4; kernel/fs/softrobotsfs/Tables.swift, kernel/core/DatabaseAccess.swift |
Schema-Text des Kernels (photo file optional), Snapshots und Zeitregler über Datenbank und Datei | gebaut | Schema.swift; Snapshots enthalten jede Datenbank (Hb. 3.59) |
Formsprache data.shape (Programme beschreiben ihre Tabellen seit 05.11.2026 als gespeicherte Formen) | noch nicht | docs/decisions.md, 05.11.2026: „Not yet: … file fields“ – shapec kann ein Datei-Feld noch nicht ausdrücken |
| App-API: Kennung einer Datei erfahren und eine Datei über ihre Kennung öffnen | geplant | Konzept 15.6: Öffnen über die Kennung ist eine Baumsuche; die Ordnerregeln gelten weiter, eine Kennung umgeht sie nie. Heute gibt files.info keine Kennung zurück. |
| Pfad zur Anzeige in Files und Console | geplant | Konzept 15.6: der Pfad wird nur zur Anzeige berechnet |
Gültig innerhalb eines Volumes. Für Programme ist das Datei-Feld damit heute im Kernel vollständig abgesichert, aber erst nutzbar, wenn Formsprache und App-API es anbieten.
9Dateiformate: was das System liest und schreibt
Jede Zeile ist mit dem Code geprüft (kernel/lib/FileTypes.swift, userland/image, svg, video, opus, sound, archive, web, sql, Manifeste der Programme, docs/api/app-api-1.txt; gelesen am 10.11.2026).
Alle Formate sind eigener Swift-Code – keine fremde Bibliothek, keine C-Abhängigkeit (beim WebP-Leser ist der Algorithmus aus libwebp portiert, Lizenz im Kopf der Datei). Decoder laufen nie im Kernel, sondern im Adressraum des Programms ohne zusätzliche Rechte:
eine bösartige Datei kann höchstens dieses Programm treffen. Öffnen und Sichern laufen seit 10.11.2026 über einen System-Dialog für alle Programme (Abschnitt 6.5, Hb. 3.135).
.reflex). Ein Programm bekommt ein Dokument nur, wenn es die Endung in seinem signierten Manifest nennt und der Anfang der Datei zum Typ passt
(PNG-Signatur, FF D8 FF, %PDF-, EBML-Kopf, „fLaC“, gültiges UTF-8 …). Eine umbenannte Datei kann sich so nicht als anderer Typ ausgeben.| Format Programm | Lesen | Schreiben | Varianten: unterstützt und nicht | Grenzen und Tempo |
|---|---|---|---|---|
| Bilder | ||||
| PNG Image, Files, Web, SVG | ja | ja | Lesen: alle Farbtypen (Grau, RGB, Palette, je mit Alpha), Bittiefen 1–16, Adam7-Interlace, tRNS-Transparenz, alle fünf Zeilenfilter, jede CRC geprüft; eigenes Inflate (RFC 1950/1951). Ergebnis immer 8 Bit RGBA (16 Bit wird reduziert). Übergangen: Gamma, Farbprofile, Text-Chunks. Nicht: APNG-Animation (es erscheint das Standardbild); ein unbekannter kritischer Chunk lehnt die Datei ab. Schreiben: 8 Bit RGB (deckend) oder RGBA, ohne Interlace, Filter je Zeile, ein IDAT, eigener Deflate. |
Lesen und Schreiben ≤ 2048 × 2048 Pixel, Datei ≤ 16 MiB; Vorschau in Files ≤ 4 MiB. Gemessen: 1024² öffnen 25,3 ms, speichern 73,0 ms; 1400 × 1400 öffnen 64 ms (Hb. 3.34). Quelle: userland/image/PNG.swift, PNGEncoder.swift, Picture.swift (maxPixels, maxFile), apps/files/Thumbnail.swift |
| JPEG Image, Files, Web, Video, Reader | ja | ja | Lesen: Baseline, Extended sequenziell (8 Bit), Progressive; Huffman; Grau, YCbCr, RGB; Unterabtastung mit Faktoren bis 4 (4:4:4, 4:2:2, 4:2:0, 4:1:1 …), Restart-Intervalle, EXIF-Ausrichtung. Höchstens 2 Stufen Abweichung zu libjpeg-turbo (mit 16-Bit-Tabellen bitgleich). Nicht: arithmetische Kodierung, 12 Bit, Lossless, CMYK. Schreiben: Baseline, YCbCr 4:2:0, Qualität 1–100 (Tabellen des Standards, skaliert wie IJG), Standard-Huffman-Tabellen, JFIF-Kopf; Alpha entfällt. |
Datei ≤ 16 MiB. Baseline mit einem Scan (Kameras) wird zeilenweise dekodiert; größer als 2048 × 2048 → verkleinert auf 1/2, 1/4 oder 1/8, also Vorlagen bis 16 384 × 16 384. Progressive und mehrere Scans: ≤ 12 Mio. Koeffizienten (rechnerisch bei 4:2:0 ≈ 8 Megapixel). Schreiben ≤ 2048 × 2048. Gemessen: 36-MP-Foto in 537 ms (SOFTrobotsVM). Quelle: userland/image/JPEG.swift, JPEGEncoder.swift, Picture.swift |
| GIF Image, Files, Web | ja | – | GIF87a und GIF89a; LZW bis 12 Bit, globale und lokale Farbtabellen, Interlace, Transparenz; Animation mit Wartezeit je Bild, Wiederholungszahl und allen drei Entsorgungsarten. Wartezeiten unter 20 ms zählen als 100 ms (wie in Browsern). Web animiert nur Sichtbares. | Bildfläche ≤ 2048 × 2048, ≤ 10 000 Bilder je Datei, Datei ≤ 16 MiB. Im Speicher liegen nur eine Leinwand und eine Kopie, nie alle Bilder. Beschädigte LZW-Daten beenden nur dieses Bild. Gemessen: 512 × 512 öffnen 3,3 ms. Quelle: userland/image/GIF.swift (maxFrames) |
| WebP Image, Files, Web | ja | – | VP8 (verlustbehaftet), VP8L (verlustfrei), VP8X mit ALPH (roh oder VP8L-komprimiert, mit Filter), Animation (ANIM/ANMF) wird in Image und Web abgespielt; ICCP, EXIF, XMP werden übersprungen. Pixel exakt wie libwebp 1.6.0 dwebp (Algorithmus aus libwebp portiert). |
Leinwand und Bild ≤ 2048 × 2048, Datei ≤ 16 MiB; VP8L-Huffman-Tabellen ≤ 222 Einträge. Beschädigte Daten geben einen Fehler, nie einen Absturz. Quelle: userland/image/WebP.swift, WebPLossless.swift, WebPAnimation.swift |
| SVG Image, Files, Web | ja | – | Eigener XML-Leser (Entitäten, CDATA, DOCTYPE übersprungen). Formen, Pfade, verschachteltes <svg>, viewBox, Verläufe, Muster, clip-path, Masken, Gruppen-Deckkraft, Marker, use/symbol, CSS, eingebettete PNG/JPEG, Text mit tspan und textPath, Filter (u. a. Weichzeichnen, Turbulenz, Licht – gegen Chrome geprüft). Nicht: Skripte, foreignObject, Animation, Verweise nach außen (nichts wird nachgeladen); bei Text kein vertikaler Text, keine Bidi-Texte, keine Ligaturen. | ≤ 100 000 Knoten, Tiefe ≤ 256, use-Verschachtelung ≤ 32, ≤ 250 000 gezeichnete Elemente, Zeichenfläche ≤ 4096 × 4096; Image liest ≤ 16 MiB, Vorschau in Files ≤ 4 MiB. Gemessen: 512 × 512 lesen und zeichnen 39,2 ms. Quelle: userland/svg/SVGDocument.swift, SVGRender.swift (maxSide, maxDrawn), SVGText.swift |
| BMP Image, Files | ja | ja | Lesen: 1, 4, 8, 16, 24, 32 Bit, Palette, Bitfelder (auch Alpha-Maske), RLE4/RLE8, oben- oder untenbeginnend. Schreiben: 24 Bit (deckend) oder 32 Bit mit Alpha (BITMAPV4-Kopf). |
≤ 2048 × 2048 Pixel, Datei ≤ 16 MiB, lesen und schreiben. Quelle: userland/image/BMP.swift, Picture.swift |
| TIFF Image, Files | ja | ja | Lesen: das erste Bild der Datei, Intel/Motorola, Streifen oder Kacheln, 1/2/4/8/16 Bit je Kanal, Grau, RGB, RGBA, Palette; unkomprimiert, PackBits, LZW, Deflate, horizontaler Prädiktor. Nicht: CMYK, YCbCr, Lab, JPEG in TIFF, Gleitkomma, getrennte Ebenen, BigTIFF, weitere Bilder der Datei. Schreiben: RGB/RGBA 8 Bit, Deflate, ein Streifen. |
≤ 2048 × 2048 Pixel, Datei ≤ 16 MiB. Gemessen: 1024² öffnen 41,1 ms, speichern 114 ms. Quelle: userland/image/TIFF.swift, Picture.swift |
| HEIC/HEIF, AVIF, JPEG 2000, JPEG XL, Kamera-RAW, ICO, PSD | nein | nein | Nicht unterstützt: kein Dokumenttyp im Kernel; solche Dateien öffnet kein Programm. JPEG 2000 in PDFs: graue Fläche. Quelle: kernel/lib/FileTypes.swift, userland/svg/PDFRender.swift | |
| Dokumente und Schriften | ||||
| PDF lesen Reader, Files (Vorschau) | ja | – | Jede Version (Kopf „%PDF-“ in den ersten 1 KiB; die Versionsnummer wird nicht ausgewertet). Querverweis-Tabellen und -Ströme (PDF 1.5), /Prev, Reparatur kaputter Tabellen, Objektströme. Filter Flate und LZW (je mit Prädiktor), ASCIIHex, ASCII85, RunLength, DCT (JPEG); Scans mit CCITT G3/G4 und JBIG2 (generisch, MMR, Symbole, Text, Verfeinerung). Farben Grau, RGB, CMYK, Lab, ICC, Index, Separation/DeviceN; Verläufe Typ 2 und 3. Verschlüsselung RC4 40/128, AES-128, AES-256 (Revision 2–6), mit Benutzer- oder Besitzerpasswort. Suchen, Markieren, Kopieren, Links. Nicht: JPEG 2000 (graue Fläche), Huffman-JBIG2 und Halbton-Bereiche (leer), JavaScript und Aktionen (nie ausgeführt); Gitter- und Funktionsverläufe nur als Mittelfarbe. | Datei ≤ 256 MiB, ein Strom ≤ 64 MiB entpackt, Verschachtelung ≤ 32, ≤ 4 Mio. Objekte, ≤ 4 Mio. Operatoren je Seite, Form-XObjects ≤ 12 tief, JBIG2-Seite ≤ 228 Pixel; Vorschau in Files ≤ 32 MiB (verschlüsselte nur ohne Passwort). 1500 zufällig beschädigte PDFs öffnen ohne Absturz (Host-Test). Quelle: userland/image/PDFReader.swift (maximumFile, maximumStream), PDFCrypto.swift, userland/svg/PDFRender.swift, PDFScan.swift, PDFJBIG2.swift |
| PDF schreiben Image (Export), App-API PDFDocument | – | ja | PDF 1.7, verschlüsselt PDF 2.0. Seitengröße frei (Vorgabe A4); Text, Linien, Rechtecke, Bilder (JPEG unverändert eingebettet, sonst Deflate mit Alpha-Maske). Schriften Helvetica, Helvetica-Bold, Courier (Standardschriften, nicht eingebettet); Zeichen Latin-1 über WinAnsi (ä, ö, ü, ß, €), andere werden „?“. Verschlüsselung AES-256 (Revision 6) – macOS öffnet sie mit dem Passwort. Nicht: eingebettete Schriften, Formulare. Image exportiert seit 10.11. über den System-Dialog (Export… mit PNG, JPEG, BMP, TIFF oder PDF). | Keine feste Grenze im Code; die Datei entsteht ganz im Speicher (keine Grenze außer Speicher). Bilder ≤ 2048 × 2048 (Bildgrenze). Quelle: userland/image/PDF.swift; Hb. 3.135 |
| Schriften Reader (in PDFs) | nur in PDF | – | Eingebettete Schriftprogramme in PDFs: TrueType (cmap 0, 4, 6, 12; zusammengesetzte Glyphen bis 8 tief), OpenType mit TrueType- oder CFF-Umrissen, CFF (Type1C, CIDFontType0C), Type 1, Type 3. Ist ein Programm nicht lesbar, zeichnet Reader mit eigener Schrift in den Breiten des PDFs. Die Systemschriften (Inter, Source Serif 4, Roboto Condensed, JetBrains Mono) werden beim Bauen auf dem Mac umgewandelt (tools/fontgen), ohne Hinting. |
Jeder Versatz im Schriftprogramm wird gegen dessen Länge geprüft. Nicht: Schriftdateien als Dokument (.ttf, .otf, .woff – kein Dokumenttyp), Web-Schriften (@font-face wird übersprungen). Quelle: userland/svg/PDFFontProgram.swift, PDFFontCFF.swift, PDFFontType1.swift, userland/web/CSSParser.swift, OutlineFont.swift |
| Word (DOC/DOCX), ODT, RTF, EPUB, PostScript/EPS | nein | nein | Nicht unterstützt: kein Dokumenttyp im Kernel. Quelle: kernel/lib/FileTypes.swift | |
| Video | ||||
| Matroska (.mkv) Video, Files | ja | ja | Eigener EBML-Code (RFC 8794/9559). Lesen: DocType matroska oder webm, Info, Tracks, Cluster, SimpleBlock und BlockGroup, Lacing Xiph/EBML/fest – nur über die Element-Köpfe, die Datei wird nie ganz geladen. Video spielt die Spuren V_MJPEG und V_VP9, Ton A_OPUS und A_PCM/INT/LIT, Erkennungen S_SOFTROBOTS/DETECTIONS; jeder andere Codec: Meldung „codec is not supported“. Schreiben in einem Durchgang (nur Anhängen): MJPEG-Bilder der Kamera unverändert mit ms-Zeitstempeln, ein Cluster je Sekunde, Cues am Ende; Erkennungen als eigene Spur, Ton als PCM-Spur. Geprüft gegen ffprobe/ffmpeg. | Lesen: Verschachtelung ≤ 16, ≤ 4 Mio. Bilder je Datei, jede Elementgröße gegen das Elternelement geprüft; Dateigröße ohne feste Grenze. Aufnahme: bei 2 GB beginnt ein neuer Teil, Ende bei weniger als 2 GB freiem Platz; keine Zeitgrenze. Quelle: userland/image/Matroska.swift, apps/video/Recording.swift (partLimit, freeLimit) |
| WebM (.webm) Video, Web (Download) | ja | – | Bild VP9, Ton Opus; ein Sprung dekodiert ab dem Schlüsselbild davor; Ton nur bei Tempo 1× (sonst stumm). Nach einem Hänger springt der Ton zur Bildzeit, statt sich zu verschieben (10.11.). Nicht: VP8, AV1, Abspielen während des Ladens; WebM schreiben (Aufnahmen sind .mkv). | Wie Matroska. Aus Web: Download ≤ 64 MiB und ≤ 10 min, dann erst abspielbar. Gemessen (10.11.2026): 57 MB von Wikimedia in 4,1 s, 13,6 MB/s (Abschnitt 6.6). Quelle: userland/image/Matroska.swift, apps/video/Codecs.swift, userland/web/HTTPMessage.swift (limit), apps/web/Fetch.swift, docs/benchmarks/network-download.md |
| VP9 (Codec) Video | ja | – | Profil 0 (8 Bit, 4:2:0) mit allen Werkzeugen: Schlüssel-, Inter-, Intra-only- und versteckte Bilder, Superframes, Compound-Prädiktion, alle Transformationen, Lossless (WHT), Segmentierung, Schleifenfilter, Kacheln, Referenzen anderer Größe. Bitgenau gegen alle 258 Testvektoren von libvpx. Seit 10.11.: bis 4 Bilder voraus dekodiert, Schleifenfilter auf 3 Kernen (bitgleich mit einem Thread), YUV→RGB mit SIMD (bytegleich). Nicht: Profile 1–3 (4:2:2, 4:4:4, 10/12 Bit) – Video zeigt einen Hinweis statt Bild. | ≤ 8192 × 8192 Abtastwerte je Bild. Gemessen in SOFTrobotsVM (10.11.2026): 1080p dekodieren 8,9 ms je Bild mit 3 Threads (1 Thread 10,5 ms), umrechnen 1,4 ms; 360p mit 60 Bildern/s: 60 von 60 gezeigt (Abschnitt 6.12). Mac (M3 Pro, Release-Build): 1080p 3,3 ms mit 3 Threads. Quelle: userland/video/VP9.swift (maxSize), VP9Loop.swift, docs/benchmarks/video-playback.md |
| Opus (Codec) Video | ja | nein | Eigener Decoder nach RFC 6716, 7845, 8251: SILK, Hybrid, CELT, Kanalzuordnung Familie 0, 1 und 255, Ausgangsverstärkung, einfache Verlust-Verdeckung; Ausgabe 48 kHz. SILK bitgenau, CELT ≈ 85 dB Abstand zur Referenz. Nicht: Fehlerkorrektur aus LBRR-Rahmen, SILK-Komfortrauschen. Opus kodieren (Aufnahme): noch nicht. | Jede Paketlänge geprüft; keine Längengrenze. Nur in WebM/Matroska – .opus-Dateien (Ogg) haben keinen Dokumenttyp. Quelle: userland/opus/Opus.swift, kernel/lib/FileTypes.swift |
| MJPEG (Codec) Video | ja | ja | JPEG-Einzelbilder in Matroska (V_MJPEG); die Aufnahme übernimmt die Bilder der Kamera ohne Neukodieren. | Je Bild die JPEG-Grenzen (oben). Quelle: userland/image/Matroska.swift, apps/video/Recording.swift |
| MP4/MOV, H.264/AVC, H.265/HEVC, MPEG-1/2, AV1, VP8, AVI | nein | nein | Nicht unterstützt: kein Container außer Matroska/WebM, kein Codec außer MJPEG und VP9. VP8 bewusst nicht (von VP9 abgelöst), AV1 später mit Hardware-Dekodierung. Quelle: kernel/lib/FileTypes.swift (nur mkv, webm), apps/video/Codecs.swift, Hb. 3.131/3.132 | |
| Ton | ||||
| WAV Sound, Files | ja | ja | Lesen: RIFF/WAVE, PCM 8/16/24/32 Bit Ganzzahl und 32 Bit Gleitkomma (auch WAVE_FORMAT_EXTENSIBLE), mono/stereo (mehr Kanäle: die ersten zwei), jede Abtastrate; Wiedergabe auf 48 kHz interpoliert, Sound rechnet intern mit 16 Bit. Nicht: komprimierte WAV (ADPCM, µ-law, A-law), 64-Bit-Gleitkomma, RF64. Schreiben: 16 Bit PCM, 48 / 44,1 / 16 kHz, mono/stereo (Aufnahme, Export). Seit 10.11. Open… und Save As… über den System-Dialog. |
Sound lädt die Datei ganz, ≤ 512 MiB (≈ 46 min Stereo, 48 kHz, 16 Bit). Aufnahme: keine Zeitgrenze im Code, alle 0,5 s auf DATA gesichert (übersteht einen Absturz). Quelle: userland/sound/WAV.swift, apps/sound/Library.swift, apps/sound/SoundFile.swift |
| FLAC Sound (Standard der Aufnahme), Files | ja | ja | Eigener Encoder und Decoder nach RFC 9639: native .flac (ID3v2-Kopf davor wird übersprungen), 4–24 Bit, 1–8 Kanäle, Raten bis 1 048 575 Hz, STREAMINFO, SEEKTABLE, MD5. Encoder: Blöcke zu 4096, je Block L/R, L/S, S/R oder M/S, LPC bis Ordnung 12, Sprungtabelle alle 10 s; die Datei ist schon während der Aufnahme abspielbar. Bitgenau gegen ffmpeg in beide Richtungen, Dateien etwa so klein wie ffmpeg Stufe 5. Sound nimmt mit 16 Bit auf (48 / 44,1 / 16 kHz, mono/stereo) und rechnet beim Öffnen auf 16 Bit und 2 Kanäle um. | Decoder liest blockweise über eine Lesefunktion: keine Grenze außer Speicher. Sound lädt ≤ 512 MiB. Aufnahme ohne Zeitgrenze. Quelle: userland/sound/FLAC.swift, FLACDecoder.swift, FLACEncoder.swift, apps/sound/Library.swift, SoundFile.swift |
| PCM in Matroska Video | ja | ja | Tonspur A_PCM/INT/LIT, 16 Bit little-endian, neben dem Bild; Video nimmt 48 kHz mono auf und spielt mono oder stereo ab. Gegen ffmpeg geprüft. | Wie Matroska. Quelle: apps/video/Codecs.swift, apps/video/RecordSound.swift |
| MP3, AAC/M4A, Ogg Vorbis, .opus, AIFF, ALAC | nein | nein | Nicht unterstützt: weder lesen noch schreiben. MP3- und Opus-Aufnahme stehen in der Planung; Programme zeigen seit 10.11.2026 nichts „später“ mehr (Inhaber, apps/sound/Look.swift).Quelle: kernel/lib/FileTypes.swift (nur wav, wave, flac), Hb. 3.134 | |
| Archive und Kompression | ||||
| ZIP Files | ja | ja | Lesen: gespeichert und Deflate, ZIP64, WinZip AES (AE-1/AE-2), ZipCrypto (nur lesen); sichere Namen (kein „..“, keine absoluten Pfade, keine Steuerzeichen), Links und versteckte Namen (.DS_Store, __MACOSX) übersprungen. Andere Verfahren (z. B. bzip2, LZMA, Deflate64) werden übersprungen. Schreiben: Deflate als Strom, UTF-8-Namen, Unix-Rechte und Zeit; Passwort nur WinZip AES-256 (AE-2, PBKDF2-HMAC-SHA1 mit 1000 Runden). |
Lesen: Dateigröße ohne feste Grenze, jeder Eintrag läuft durch ≈ 130 KiB Speicher; das zentrale Verzeichnis muss im letzten 1 MiB der Datei liegen. Schreiben: ≤ 4 GiB je Datei und Archiv, ≤ 65 535 Einträge (kein ZIP64 beim Schreiben). Vorschau in Files ≤ 64 MiB. Gemessen: Deflate 4 MiB 166 MB/s; 3 000 000 gemischte Bytes → 605 816 Bytes (Mac-Test, Hb. Kap. 6). Quelle: userland/archive/ZipReader.swift (tailLimit), ZipWriter.swift, ZipCipher.swift, StreamInflate.swift, apps/files/Archives.swift |
| Deflate / zlib / gzip PNG, ZIP, PDF, TIFF, Web | ja | ja | Ein Inflate (RFC 1950/1951) für alle Formate, auch als Strom in Stücken bis 64 KiB; gzip nur als HTTP-Content-Encoding in Web. Deflate: Hash-Ketten über 32 KiB, ≤ 32 Kandidaten, ein Schritt Lazy Matching; jeder Block (≤ 16 384 Symbole oder 64 KiB) dynamisch, fest oder gespeichert – je nachdem, was kleiner ist. | Ausgabe immer mit Obergrenze: PNG die berechnete Bildgröße, PDF 64 MiB je Strom, gzip in Web 64 MiB; im Strom (ZIP) ohne Grenze. Quelle: userland/image/Inflate.swift, userland/archive/StreamInflate.swift, Deflate.swift, apps/web/Fetch.swift |
| tar, .gz als Datei, 7z, RAR, bzip2, xz, Zstandard | nein | nein | Nicht unterstützt: kein Dokumenttyp im Kernel. Quelle: kernel/lib/FileTypes.swift | |
| Web | ||||
| HTML und CSS Web | ja | – | Lesebrowser ohne JavaScript: toleranter HTML-Leser (implizite End-Tags, <script> übersprungen, <noscript> gezeigt), CSS-Selektoren und -Werte, @media (Breite, Höhe, screen, helles Farbschema), @supports, @layer, @import. Bilder aller obigen Bildformate (auch data:-Adressen), <video> als Karte „Play in Video“. HTTP/1.1 (GET, chunked, gzip) über TLS 1.3, ohne Cookies und Referrer. Eigene Umrissschriften mit Kerning. Seit 10.11.: File › Open… öffnet eine .html-Datei, Save Page As… sichert die gezeigte Seite unverändert. Nicht: JavaScript, Cookies, @font-face, @keyframes, verschachtelte CSS-Regeln. | ≤ 100 000 Knoten, Tiefe ≤ 256; ein Stylesheet ≤ 4 MiB, ≤ 16 externe mit zusammen < 4 MiB; Antwort ≤ 64 MiB; ≤ 600 Bilder je Seite und ≤ 160 MiB dekodierte Bildpixel; SVG-Bilder ≤ 4096 × 4096. Eine Seite hat 20 s, ein Download bis 10 min. Quelle: userland/web/HTML.swift, CSSParser.swift, HTTPMessage.swift, apps/web/Images.swift, apps/web/main.swift, apps/web/Fetch.swift |
| Daten und Tabellen | ||||
| SOFTrobotsDB (.db) Programme (App-API); Database, Console | ja | ja | Eigenes Objekt im Dateisystem (Abschnitt 8). Database und Console lesen jede Datenbank, schreiben nur im eigenen Ordner. | Datensatz ≤ 4096 Bytes, 64 Tabellen je Datenbank, 64 Felder je Tabelle, Transaktion ≤ 4 MiB, ≤ 256 Zeilen je Abfrage-Aufruf (dann Cursor); große Daten als Datei-Feld (8.5). Quelle: Abschnitte 8 und 14, docs/handbuch/grenzen.html |
| Serien (.series), Flugschreiber Echtzeit-Programme; Database, Console | ja | ja | Datensätze fester Größe mit Zeitstempel in 16-KiB-Blöcken, Zeitindex im Datenbank-Baum. | Datensatz 8–1024 Bytes; Aufnahme-Ring 1–600 s, ≤ 32 MiB, 16 Ringe im System. Quelle: Abschnitte 8 und 14 |
| SQL Console, Database | ja | – | Nur lesend: SELECT mit WHERE, GROUP BY, ORDER BY, LIMIT, COUNT/SUM/MIN/MAX/AVG, BETWEEN, LIKE (beginnt mit / enthält), IS NULL, LEFT/INNER JOIN über ref-Felder. Im Programm in den festen Bauplan des Kernels übersetzt. Nicht: INSERT, UPDATE, DELETE, Unterabfragen. | ≤ 4 Joins (2 davon für WHERE/ORDER BY); Sortieren ohne Index Top-N ≤ 1000; ≤ 256 Gruppen. Quelle: userland/sql/SQL.swift, Abschnitt 14 |
| CSV Export: Database, Console, Benchmark; Text | ja | ja | Export: alle Zeilen der Abfrage (nicht nur die 1000 gezeichneten), Texte ganz, Anführungszeichen verdoppelt; Database fragt seit 10.11. über den System-Dialog, wohin. Text liest und bearbeitet CSV als Text. | Export: keine Zeilengrenze. Text hält ≤ 4 MiB im Speicher. Quelle: apps/database/Export.swift, apps/text/main.swift (textLimit) |
| JSON Export: Database, Console, Benchmark; Text | ja | ja | Export wie CSV, Texte maskiert. Text liest und bearbeitet JSON als Text. | Wie CSV. Quelle: apps/database/Export.swift, apps/text/main.swift |
| Text | ||||
| Text, Markdown, Log, Einstellungen Text, Files | ja | ja | Endungen txt, text, md, markdown, log, csv, json, conf und die Datei config; gültiges UTF-8 ohne NUL-Bytes ist Pflicht (der Kernel prüft es). ⌘S speichert; seit 10.11. New, Open… und Save As… über den System-Dialog – Text legt damit erstmals neue Dateien an. |
Text hält ≤ 4 MiB im Speicher. Quelle: kernel/lib/FileTypes.swift, apps/text/main.swift; Hb. 3.135 |
| Absturzberichte (.crash) Kernel schreibt, Monitor zeigt | ja | ja | Text in DATA /state/crashes; seit Hb. 3.89 mit Bildern von Bildschirm und Kamera. | 20 Dateien, je ≤ 1 MiB. Quelle: Abschnitt 14, docs/handbuch/grenzen.html |
| Signierte Systemformate | ||||
| Programme (ELF + Manifest) Kernel lädt; Develop, Mac-Werkzeug srapp | ja | ja | AArch64-ELF, Ed25519-signiert; das Manifest trägt Rechte, Echtzeit-Vertrag und Speicherzusage (seit 10.11. auch dock = no). |
≤ 32 MiB, ≤ 8 Segmente. Quelle: kernel/lib/AppImage.swift (largestFile, maxSegments), kernel/lib/AppManifest.swift |
| .srmodel (KI-Modelle) Video liest; Mac: modelconv, sign model | ja | Mac | int8-Modelle für die eigene Inferenz; Ed25519-Signatur in den letzten 96 Bytes, davor ein mitsignierter 256-Byte-Infoblock (Name, Version, Lizenz, Herkunft). Ohne gültige Signatur verweigert der Kernel das Lesen. | Video lädt Modelle ≤ 64 MiB. Quelle: apps/video/Models.swift |
ONNXtools/infer/modelconv.py | nur Mac | – | Ein Float-ONNX-Detektor wird auf dem Mac mit eigenen Kalibrierbildern zu int8 quantisiert und in .srmodel umgewandelt. Im System läuft keine fremde Laufzeit. | Unbekannte Operatoren werden abgelehnt. Quelle: tools/infer/modelconv.py |
| .srshare (Reflex-Skript) Develop | ja | ja | Geteiltes Reflex-Skript („SOFTrobots share 1“), signiert; Develop zeigt es auf einer Prüfkarte, bevor es übernommen wird. Seit 10.11. fragt Share…, wohin das Paket soll (vorher fest in den eigenen Ordner und den Mac-Ordner); Import… über den System-Dialog. | Keine eigene Größengrenze im Code gefunden (nicht geprüft). Quelle: apps/develop/Share.swift, kernel/lib/FileTypes.swift; Hb. 3.135 |
| .reflex Develop, Files | ja | ja | Quelltext der Sprache Reflex; übersetzt zu Bytecode oder ARM64. Seit 10.11.2026 eigener Dokumenttyp „Reflex script“ im Kernel (gültiges UTF-8 Pflicht); ein Doppelklick in Files übernimmt das Skript in Develop; Import… und Export… ⌘E über den System-Dialog. | Editor ≤ 1 MiB Quelltext. Quelle: apps/develop/Editor.swift (limit), kernel/lib/FileTypes.swift (reflex = 24); Hb. 3.135 |
| .srupdate Kernel liest; Mac-Werkzeug sign | ja | Mac | Signiertes Update-Paket (Ed25519): Kernel und belegte Blöcke des Systemvolumes; falsche Signatur wird abgelehnt (make test-update). |
≤ 4064 Systemblöcke zu 16 KiB (≈ 63,5 MiB) plus Kernel. Quelle: kernel/lib/UpdatePackage.swift (maxBlocks) |
| QR-Code Server (Einladung) | – | ja | Byte-Modus (UTF-8-Text als Bytes), alle vier Fehlerkorrektur-Stufen, alle acht Masken bewertet; mit Apples Vision gegengelesen (Host-Test). | Versionen 1–10 (21 × 21 bis 57 × 57 Module), ≤ 271 Bytes (Stufe L) bzw. 213 (M). Gemessen: Version 4 in 410 µs, Version 10 in 1,3 ms. Quelle: userland/qr/QRCode.swift |
35 Formate und Codecs werden gelesen oder geschrieben; die grauen Zeilen „nein“ nennen, was ausdrücklich fehlt. Grenzen sind Konstanten aus dem genannten Quelltext (gelesen am 10.11.2026), Tempo-Werte aus SOFTrobotsVM, sofern nicht als Mac-Wert vermerkt. Nachweise wie „bitgenau“ und „pixelgleich“ stammen aus den Host-Tests (Handbuch 3.34–3.37, 3.70–3.76, 3.102, 3.121, 3.129–3.137). Ein Format ohne eigene Zeile wird nicht unterstützt: der Kernel gibt einem Programm nur Dateien der 24 bekannten Dokumenttypen.
10Boot-Grafik und Boot-Zeiten
Die Start-Animation zeichnet der Kernel selbst – mit Ganzzahl-Arithmetik, weil der Kernel kein Gleitkomma benutzt: abgerundete Rechtecke, Ellipsen, Ringe, Kapseln und vorgerenderte Textmasken, Kanten mit 4 × 4 Abtastungen geglättet. Ein Thread niedriger Priorität zeichnet etwa 30 Bilder pro Sekunde (gemessen: 275 Bilder während der 10-s-Fassung, Boot-Log 08.11.2026).
- Ablauf (2,3 s seit 10.11.2026; 09.11.: 5 s; davor 10 s): Der kleine Roboter mit Bildschirmgesicht ist ab dem ersten Bild da: Der Kopf hebt sich, das Gesicht geht an, er öffnet die Augen, lächelt und winkt;
Schriftzug „SOFTrobots OS“ und Geburtstagszeile („born 28 October 2026 · N days old“) erscheinen, dann ist der Desktop da. Die Code-Wolke vom Anfang ist entfernt (Inhaber: „dann können wir noch schneller booten“;
kernel/core/BootScreen.swift,duration2,3 s). Gemessen mit der 5-s-Fassung: Desktop 5,7 s statt 10,7 s nach dem Einschalten (SOFTrobotsVM, Hb. 3.127); mit 2,3 s noch nicht gemessen. - Startton: ein Dreiklang 0,3 s nach dem Start (Variante b des Inhabers), Servo-Surren beim Winken – aus dem Mischer des Kernels, ohne Gleitkomma; ohne Tongerät bleibt es still. Startet das Tongerät später, spielt es den ganzen Akkord, sobald es kann.
- Die Schichtenzeile ist echt: Unten erscheinen nacheinander Firmware, Kernel, Devices, Storage, Network, Programs und Ready, jede mit der gemessenen Zeit, zu der diese Schicht im Kern fertig war.
- Das System wartet nicht auf die Animation: Dienste, Echtzeitschleifen und Programme laufen dahinter wie ohne sie. Nur der Desktop fragt (Systeminfo), ob sie noch läuft. Jede Taste oder jeder Klick überspringt sie; ⌘+Esc löst auch währenddessen den Not-Halt aus.
- Ohne Flackern: mit virtio-gpu entsteht jedes Bild im Gastspeicher und wird per Flush gezeigt; nur mit GOP (echte Hardware ohne Grafiktreiber) in einem Zwischenpuffer, der fertig hinüberkopiert wird.
- Textzeilen statt Animation: Taste V beim Einschalten, Datei
\SOFTROBOTS\VERBOSE(Testabbilder), ein zurückgerolltes Update, ein Panic oder die Einstellung „Start screen: Text“ (im Boot-Record, damit der Loader sie vor dem Entsperren lesen kann).
Boot-Zeiten
| Schicht fertig | Sekunden nach dem Einschalten |
|---|---|
| Firmware | 0,52 s |
| Kernel | 0,53 s |
| Devices | 0,55 s |
| Storage | 0,58 s |
| Network | 0,58 s |
| Programs | 0,63 s |
| Ready (Hello) | 0,64 s |
| IPv4-Adresse per DHCP (Hintergrund) | 1,18 s |
Quelle der Schichtzeiten: die Zeile unter der Boot-Animation im Bild oben (SOFTrobotsVM, Produktabbild 0.15.0, 08.11.2026). „Hello“ im Messlauf desselben Tages: 0,66 s. Firmware und Loader brauchen davon etwa 0,5 s; der Kernel selbst rund 90 ms. In QEMU dauert es bis „Hello“ etwa 6 s – fast nur emulierte Firmware.
11Echtzeit-Prozessor
Ein Roboterarm wird von einem Regelkreis gesteuert, der jede Millisekunde Sensoren liest und Motoren nachstellt. „Schnell im Durchschnitt“ reicht nicht – der Takt muss garantiert pünktlich sein. Dafür reserviert SOFTrobots OS den letzten Prozessorkern als Echtzeitkern.
Vertrag im signierten Manifest
realtime = 1000 100 stop heißt: Periode 1000 µs (1 kHz, das Periodenende ist die Frist), Budget 100 µs CPU-Zeit je Periode, Reaktion bei verpasster Frist
log, stop, restart oder stop-actuators. Das Programm beendet jede Periode mit dem Grundbefehl periodWait.
Zulassung: Passt die Summe der Budgets nicht mehr auf den Echtzeitkern (≤ 900 ‰), wird das Programm gar nicht erst gestartet – statt später unberechenbar zu scheitern.
Was der Echtzeitkern garantiert
- Keine anderen Threads, keine Lastverteilung auf oder von ihm, kein
wfi-Schlaf. - Kein Heap und kein Dateizugriff für Echtzeit-Programme; nie ausgelagert.
- Asynchrones Kernel-Log: Schreiber warten nie auf Konsole oder GPU.
- Watchdog alle 50 ms; Zähler für Perioden, verpasste Fristen, mittlere und schlechteste Verspätung (Desktop-Karte ROBOT & REALTIME).
| Messung (SOFTrobotsVM) | Gemessen | Ziel | Urteil |
|---|---|---|---|
| IRQ-Latenz (Deadline → Handler), Mittel | 51,0 ns | < 10 µs | erfüllt |
| IRQ-Latenz, schlechteste | 375 ns | < 10 µs | erfüllt |
| Kontextwechsel | 0,3 µs | < 2 µs | erfüllt |
| Nachricht hin und zurück (IPC) | 1,5 µs | < 1 µs | knapp verfehlt (1,5 µs; vorher 14,5) |
| Echtzeit-Aufwachen 1 ms, Mittel | 1,1 µs | < 20 µs | erfüllt |
| Echtzeit-Aufwachen 1 ms, schlechteste | 44,3 µs | < 20 µs | in 1 von 3 Läufen verfehlt (sonst 6–7 µs) |
| Echtzeit-Programm 1 kHz: Startverzögerung Mittel / schlechteste | 0,13 µs / 0,5–16 µs (im Boot 26–77 µs) | < 20 µs | erfüllt nach dem Start |
| Verpasste Perioden in 10 s | 0 | 0 | erfüllt |
Quellen: Kernel-Selbsttest mit Hintergrundlast im Benchmark-Start vom 08.11.2026 (Boot-Log: „Realtime wake-up (1 ms period, CPU 2): min/avg/max 0.6/1.1/44.3 us, 0 missed“, die anderen zwei Läufe 6,1 und 6,8 µs);
Testprogramm control mit 1-kHz-Vertrag (Phase 9, Handbuch Kapitel 6, 10 s ohne verpasste Periode). Seit F143 (08.11.2026) sind Systemaufrufe unterbrechbar: Startet auf demselben Kern ein großes Programm,
kommt ein Takt höchstens 6–7 µs zu spät statt bis 0,9 ms (docs/decisions.md). Develop beweist Echtzeit sogar vorab: Für „Wrist hold“ wurden 41,1 µs von 1 ms (4,1 %) als schlechtester Fall berechnet.
Echte Hardware ist noch nicht gemessen.
12Geschwindigkeit in Zahlen (Programm Benchmark)
Das Programm Benchmark misst jeden Baustein einzeln: 80 Messungen in 15 Bereichen. Jede Messung hat eine feste Nummer, die ihre Bedeutung nie ändert, damit Läufe aller Versionen vergleichbar sind.
Jeder Lauf wird in /data/benchmark/runs.db (einer SOFTrobotsDB-Datenbank) gespeichert; nach einem Update misst Benchmark von selbst. Werte des Kernels (Start, Scheduler, NVMe, Dateisystem, Plattenverschlüsselung, Programmstart, Passwortprüfung) werden beim Boot gemessen und übernommen.
apps/benchmark/Metrics.swift.Prozessor-Speedtests (Bereich „Processor, memory“)
| Nr. | Messung | Wert | Bemerkung |
|---|---|---|---|
| 40 | CRC-32 over 16 MiB | 344 MB/s | Benchmark-Lauf |
| 41 | Floating point (matrix 128 x 128) | 2883 Mio./s | Benchmark-Lauf |
| 42 | Memory copy (32 MiB) | 3811 MB/s | Benchmark-Lauf |
| 43 | Memory fill (32 MiB) | 5573 MB/s | Benchmark-Lauf |
| 44 | Heap: allocate and free an object | 125 ns | Benchmark-Lauf |
Alle Messungen
| Nr. | Messung | Wert | Bemerkung |
|---|---|---|---|
| Start · Start | |||
| 1 | Power on to "Hello from the kernel." | 0,66 s | Firmware + Loader + Kernel bis „Hello“ |
| Scheduler, Echtzeit · Scheduler, realtime | |||
| 10 | Interrupt latency, average | 51,0 ns | Kernel-Messung beim Start |
| 11 | Interrupt latency, worst | 375 ns | Kernel-Messung beim Start |
| 12 | Context switch | 0,3 µs | nach F142 (vorher 2,9 µs) |
| 13 | Scheduling decision | 0,2 µs | Kernel-Messung beim Start |
| 14 | Realtime wake-up (1 ms), average | 1,1 µs | während Benchmark startet (F143) |
| 15 | Realtime wake-up (1 ms), worst | 44,3 µs | während Benchmark startet; die anderen zwei Läufe: 6,1 und 6,8 µs |
| 16 | Realtime periods missed at boot | 0 | Kernel-Messung beim Start |
| 17 | Sleep 1 ms: late by, average | 264 µs | Zeitgeber-Auflösung für Programme |
| 18 | Yield to the scheduler | 1,2 µs | Benchmark-Lauf |
| Nachrichten (IPC) · Messages (IPC) | |||
| 20 | Message sent and received | 1,5 µs | Programme auf verschiedenen Kernen (F143); auf demselben Kern 8,4 µs |
| 21 | Wake the other end (notify) | 2,9 ns | nur noch, wenn die Gegenseite schläft (F143) |
| 22 | Messages through a channel | 1,8 Mio./s | Benchmark-Lauf |
| Programme · Programs | |||
| 30 | Start and end a program | nur Testabbild | im Produktabbild nicht gemessen (Testprogramm) |
| 31 | Start from the app cache | nur Testabbild | im Produktabbild nicht gemessen (Testprogramm) |
| 32 | System call (time) | 819 ns | Benchmark-Lauf |
| 33 | System information read (system.info) | 4,9 µs | Benchmark-Lauf |
| 34 | Installed programs listed (all, with id and version) | 607 µs | Benchmark-Lauf |
| Prozessor, Speicher · Processor, memory | |||
| 40 | CRC-32 over 16 MiB | 344 MB/s | Benchmark-Lauf |
| 41 | Floating point (matrix 128 x 128) | 2883 Mio./s | Benchmark-Lauf |
| 42 | Memory copy (32 MiB) | 3811 MB/s | Benchmark-Lauf |
| 43 | Memory fill (32 MiB) | 5573 MB/s | Benchmark-Lauf |
| 44 | Heap: allocate and free an object | 125 ns | Benchmark-Lauf |
| Platte (NVMe) · Disk (NVMe) | |||
| 50 | Read 16 KiB, one command | 50,3 µs | Kernel-Messung beim Start |
| 51 | Write 16 KiB, one command | 97,6 µs | Kernel-Messung beim Start |
| 52 | Sequential read (16 commands at once) | 1073 MB/s | Kernel-Messung beim Start |
| 53 | Sequential write (16 commands at once) | 443 MB/s | Kernel-Messung beim Start |
| Dateisystem · File system | |||
| 60 | Kernel: 4 MiB written and committed | 204 MB/s | Kernel-Messung beim Start |
| 61 | Kernel: 4 MiB read and checked | 521 MB/s | Kernel-Messung beim Start |
| 62 | App: 4 MiB file written | 113 MB/s | Benchmark-Lauf |
| 63 | App: 4 MiB file read | 239 MB/s | Benchmark-Lauf |
| 64 | Small file created and removed | 8,9 ms | Benchmark-Lauf |
| 65 | Folder entry listed | 394 µs | Benchmark-Lauf |
| Datenbank · Database | |||
| 70 | 1000 rows inserted (on disk) | 22,2 ms | Benchmark-Lauf |
| 71 | 1000 rows inserted (soon) | 10,3 ms | Benchmark-Lauf |
| 72 | Row by id | 30,4 µs | Benchmark-Lauf |
| 73 | Range through an index (100 rows) | 5,2 ms | Benchmark-Lauf |
| 74 | Sorted without an index (top 100 of 1000) | 29,0 ms | Benchmark-Lauf |
| 75 | Count in groups (1000 rows) | 3,8 ms | Benchmark-Lauf |
| 76 | SQL statement translated | 3,5 µs | Benchmark-Lauf |
| Serien, Aufzeichnung · Series, recording | |||
| 80 | Records pushed into the ring | 1,1 Mio./s | Benchmark-Lauf |
| 81 | Records dropped (10 000 pushed) | 0 | Benchmark-Lauf |
| 82 | Time range read back (1000 records) | 14,2 ms | Benchmark-Lauf |
| Bilder, ZIP · Pictures, ZIP | |||
| 90 | PNG 1024 x 1024 saved | 73,0 ms | Benchmark-Lauf |
| 91 | PNG 1024 x 1024 opened | 25,3 ms | Benchmark-Lauf |
| 92 | JPEG 1024 x 1024 saved | 21,6 ms | Benchmark-Lauf |
| 93 | JPEG 1024 x 1024 opened | 15,1 ms | Benchmark-Lauf |
| 94 | Deflate (ZIP) 4 MiB | 166 MB/s | Benchmark-Lauf |
| 95 | GIF 512 x 512 opened | 3,3 ms | Benchmark-Lauf |
| 96 | TIFF 1024 x 1024 saved | 114 ms | Benchmark-Lauf |
| 97 | TIFF 1024 x 1024 opened | 41,1 ms | Benchmark-Lauf |
| 98 | SVG drawing read and drawn (512 x 512) | 39,2 ms | Benchmark-Lauf |
| Anzeige · Display | |||
| 100 | Whole picture 1280 x 800 filled | 2672/s | Benchmark-Lauf |
| 101 | Characters drawn | 4,5 Mio./s | Benchmark-Lauf |
| 102 | Window drawn and shown | braucht Fenster | braucht ein offenes Fenster; der Lauf ohne Fenster lässt sie aus |
| 103 | Key mapped (German layout, umlauts) | 6,4 ns | Benchmark-Lauf |
| 104 | Key typed into a text field | 17,5 ns | Benchmark-Lauf |
| 105 | Text field drawn | 26,4 µs | Benchmark-Lauf |
| Verschlüsselung · Encryption | |||
| 110 | Disk: AES-256-GCM seal (hardware) | 3197 MB/s | Kernel-Messung beim Start |
| 111 | Disk: AES-256-GCM open (hardware) | 2945 MB/s | Kernel-Messung beim Start |
| 112 | SHA-256 | 139 MB/s | Benchmark-Lauf |
| 113 | AES-256-GCM in an app | 37,7 MB/s | Benchmark-Lauf |
| 114 | ChaCha20-Poly1305 in an app | 48,8 MB/s | Benchmark-Lauf |
| 115 | Ed25519 signature checked | 500 µs | Benchmark-Lauf |
| 116 | Password check (Argon2id, 64 MiB) | 277 ms | Kernel-Messung beim Start |
| 117 | ECDSA P-256 signature made | 3,2 ms | Benchmark-Lauf |
| 118 | ECDSA P-256 signature checked | 2,5 ms | Benchmark-Lauf |
| Netzwerk · Network | |||
| 120 | Name resolved (DNS over HTTPS) | 115 ms | Benchmark-Lauf |
| 121 | TLS 1.3 handshake | 79,7 ms | Benchmark-Lauf |
| 122 | HTTPS page fetched (example.com) | 317 ms | Benchmark-Lauf |
| Server, Zertifikate · Server, certificates | |||
| 130 | Robot's root certificate made | 11,0 ms | Benchmark-Lauf |
| 131 | Server certificate issued by the root | 9,0 ms | Benchmark-Lauf |
| 132 | TLS 1.3 handshake, own server and client in memory | 7,7 ms | Benchmark-Lauf |
| 133 | TLS 1.3 data, server to client in memory | 23,6 MB/s | Benchmark-Lauf |
| 134 | HTTP request head read (browser request) | 4,9 µs | Benchmark-Lauf |
| 135 | QR code made (version 4) | 410 µs | Benchmark-Lauf |
| 136 | QR code made (version 10) | 1,3 ms | Benchmark-Lauf |
| Develop (Reflex) · Develop (Reflex) | |||
| 140 | Reflex: system shapes read (catalog) | 2,8 ms | Benchmark-Lauf |
| 141 | Reflex: example program compiled | 60,7 µs | Benchmark-Lauf |
| 142 | Reflex: periodic handler run (interpreter) | 1,4 µs | Benchmark-Lauf |
Weitere Messwerte aus Boot-Log und Handbuch
| Messung | Wert | Wo / wie gemessen |
|---|---|---|
| System und Programme | ||
| Programm aus dem App-Cache starten | 53–56 µs | SOFTrobotsVM, Phase 14 (erster Start ca. 2 ms); Code und Konstanten geteilt |
| Programm starten und beenden (Lebenszyklus) | 0,77–0,80 ms | SOFTrobotsVM, Handbuch Kapitel 6 |
| Signaturprüfung je Programm beim Start / Hashen aller Programme | 430 µs / 3,3 ms | Boot-Log 08.11.2026: 6 MiB, SHA-256 mit Prozessorbefehlen |
| Fair Share mit Gewichten 2 : 1 | 2,0 | Boot-Log 08.11.: 66 ms : 33 ms |
| Kontextwechsel im Verlauf | 4,3 → 0,3 µs | erste Version 4,3 µs (Struct-Kopien), Bestwert 0,1 µs; heute 0,3 µs nach F142 (vorher 2,9 µs) |
| Nachricht hin und zurück im Verlauf | 14,5 → 1,5 µs | F143, 08.11.2026: Merkzeichen im Ring spart den Weck-Aufruf, wenn die Gegenseite wartet |
| Krypto im Kernel (Boot-Log 08.11.2026) | ||
| SHA-256 mit Prozessorbefehlen | 2149 MB/s | in einem Programm ohne diese Befehle: 139 MB/s (Benchmark) |
| X25519-Schlüsseltausch | 10 322 /s | anfangs 23 /s (Handbuch Kapitel 6) |
| ChaCha20-Poly1305 | 57,8 MB/s | Software |
| Argon2id je Passwortprüfung (64 MiB, 3 Durchläufe) | 277 ms | absichtlich teuer: bremst Raten |
| Netz und Caches (Hb. 3.93, je drei Läufe vorher/nachher in SOFTrobotsVM) | ||
| 8 neue Namen über DNS über HTTPS | 1014 → 455 ms | Verbindung bleibt offen, 64 statt 8 Namen im Cache |
| 8 Abrufe vom selben Webserver | 2329 → 448 ms | Keep-Alive; etwa 235 ms pro Bild gespart |
| Startzeit bis „Hello“ mit SHA-256 in Hardware | 0,686 → 0,652 s | Hashen beim Start 48,6 → 3,4 ms |
| Medien | ||
| Objekterkennung je Kamerabild (int8, 3 Kerne) | 44 ms | SOFTrobotsVM; erste Fassung 213 ms; ruhige Bilder: 75 % der Läufe gespart (Hb. 3.93) |
| JPEG 640 × 480 dekodieren (Kamerabild) | 4 ms | SOFTrobotsVM, Video |
| ZIP mit Passwort entpacken / 6 Dateien (10,3 MiB) packen | 61 / 655 ms | SOFTrobotsVM, AES in Software |
| PDF-Seite zeichnen (eine Seite des Datenblatts) | ≈ 0,06 s | Mac, Host-Test (Hb. 3.130) – kein VM-Wert |
Video und Downloads (10.11.2026, docs/benchmarks/video-playback.md, network-download.md) | ||
| VP9 1080p dekodieren je Bild, 3 Threads / 1 Thread | 8,9 / 10,5 ms | SOFTrobotsVM, make vm-vp9-bench, 600 Bilder; vorher 13,0 / 15,5 ms (Abschnitt 6.12) |
| YUV → RGB umrechnen, 1080p je Bild | 1,4 ms | SOFTrobotsVM; vorher 4,3 ms; in einen gehaltenen Puffer 1,1 ms |
| 360p-Video mit 60 Bildern/s: gezeigt je Sekunde | 60 von 60 | SOFTrobotsVM, Big Buck Bunny; ohne Vordekodieren 3–14 von 60 |
| HTTPS-Download 57 MB von Wikimedia | 2,7 → 13,6 MB/s | SOFTrobotsVM, Mac im WLAN; 4,1 s statt etwa 21 s; 1-MiB-Empfangsfenster (Abschnitt 6.6) |
13Warum es schnell ist – Gründe, Belege und Schätzungen
Hier steht, was SOFTrobots OS schneller macht, woran man es misst und – wo es keinen eigenen Vergleichswert gibt – um wie viel es nach unserer Schätzung besser ist als übliche Allzweck-Systeme. Jede Schätzung nennt ihren Grund; Vergleichsmessungen fremder Systeme haben wir nicht gemacht.
| Baustein | Was wir anders machen | Beleg (gemessen) | Vorteil |
|---|---|---|---|
| Start | Kleiner Kernel (1,10 MiB geladen), keine Suche nach Altgeräten, Messungen und Selbsttests erst nach „Hello“, nichts auf dem Boot-Weg wartet auf das Netz. | 0,66 s bis „Hello“, davon Kernel ≈ 90 ms, Rest Firmware und Loader; Desktop nach 5,7 s (mit 5-s-Animation; seit 10.11. 2,3 s, noch nicht gemessen) | Die Kernel-Zeit ist kleiner als die der Firmware; schneller geht es nur mit schnellerer Firmware. |
| Interrupts und Echtzeit | Reservierter Echtzeitkern ohne wfi, tickloser Zeitgeber im One-Shot-Betrieb, kurze obere Hälften, unterbrechbare Systemaufrufe, asynchrones Log. |
IRQ 51,0 ns Ø, Aufwachen 1,1 µs Ø, 0 verpasst | Ziele (< 10 µs bzw. < 20 µs) im Mittel um das 200- bzw. 18-Fache unterschritten. Echtzeit ist ein Vertrag mit Zulassung, keine Einstellung. |
| Kontextwechsel | Heiße Scheduler-Methoden ohne Struct-Kopien, Per-CPU-Zustand nie in Optional; Lazy FP/SIMD. | 0,3 µs; Entscheidung allein 0,2 µs | gemessen 14-mal schneller als die erste Fassung (4,3 µs) |
| Kommunikation zwischen Programmen | Kanäle sind gemeinsame Seiten mit zwei Ringen; der Kernel kopiert nie eine Nachricht. Wartet die Gegenseite, entfällt der Weck-Aufruf ganz. | 1,5 µs hin und zurück; 1,8 Mio./s Nachrichten; notify 2,9 ns | Schätzung keine Serialisierung und keine Kernel-Kopie: je Nachricht entfallen zwei Kopien gegenüber Pipes/Sockets. Ziel 1 µs ist noch knapp verfehlt. |
| Plattenverschlüsselung | AES-256-GCM mit den ARM-Krypto-Befehlen in eigenem Assembler (crypto.S), je Block, mit Schutz gegen zurückgespielte Blöcke. |
3197 MB/s / 2945 MB/s; Software-AES im Programm 37,7 MB/s | gemessen 85-mal schneller als Software; fast 3-mal schneller als die VM-Platte liest – Verschlüsselung ist nicht der Engpass. |
| Prüfsummen und Signaturen | CRC-32C und SHA-256 mit Prozessorbefehlen; geprüfte Programme merkt sich der App-Cache. | SHA-256 2149 MB/s; Signatur je Programm 430 µs | gemessen 14-mal schneller als vorher (150 MB/s) |
| Dateisystem | Kein Journal; Block = Seite = Baumknoten = DMA-Puffer; gebündelter Commit mit FUA; kein atime; kleine Dateien im Baum; Freiplatz-Karte auf der Platte. | 4 MiB 204 MB/s schreiben, 521 MB/s lesen; 280 Dateien in einem Commit 4,2 ms; Einbinden 11 ms | Schätzung bis zu halb so viele Schreibvorgänge je Änderung wie ein Journal-Dateisystem, das Daten journalt (jede Änderung einmal statt zweimal); ein Flush + FUA statt zwei Flushes je Commit. |
| Datenbank | Commit des Dateisystems = Commit der Datenbank; ein Systemaufruf je Transaktion; Abfragen im Kernel; Ringe für Messwerte; große Daten als Datei (8.4, 8.5). | Zeile nach Id 30,4 µs; 1000 Zeilen 10,3 ms; Ring 1,1 Mio./s | Schätzung 2- bis 3-mal weniger Flushes je kleinem dauerhaftem Commit; bei großen Werten etwa halb so viel Schreibvolumen; Messwerte aus Echtzeit-Code: ohne Gegenstück. |
| Speicher | 16-KiB-Seiten und 32-MiB-Blöcke (weniger TLB-Fehlgriffe), Zusagen statt Überbuchung, Auslagerung nur in den eigenen Bereich des Programms; Echtzeit nie ausgelagert. | Speicher kopieren 3811 MB/s, füllen 5573 MB/s; Heap-Objekt 125 ns | Schätzung 16 KiB statt 4 KiB: ein TLB-Eintrag deckt die vierfache Fläche ab. |
| Netz | Eigener Stack im Kernel mit Interrupts statt Polling, Window Scaling, offene Verbindungen für DoH und Web, Zurück aus dem Speicher; große Downloads bekommen ein 1-MiB-Empfangsfenster. | Ping 0,1 ms; 8 Web-Abrufe 2329 → 448 ms; Download 2,7 → 13,6 MB/s | gemessen 5-mal schneller durch Keep-Alive und 5-mal schneller beim Download (10.11.); Polling → Interrupts: Ping 5-mal schneller (2,5 → 0,5 ms, Phase 6) |
| Video | Vordekodieren und Aufholen der Reihe nach, Schleifenfilter auf 3 Kernen, Farbumrechnung mit SIMD, Programme mit Heap ohne Strict Alignment, Video mit -O gebaut. | 1080p dekodieren 13,0 → 8,9 ms, umrechnen 4,3 → 1,4 ms je Bild; 360p 60 von 60 Bildern | gemessen 1,5-mal schneller dekodiert und 3-mal schneller umgerechnet (VM, 10.11.); zusammen ≈ 10 ms von 16,7 ms je Bild bei 60 Bildern/s |
| Erkennung im Gerät | Eigene int8-Inferenz mit sdot-Assembler, auf 3 Kerne verteilt; unveränderte Bilder werden nicht neu erkannt. | 44 ms je Bild; 75 % der Läufe bei ruhigem Bild gespart | gemessen 4,8-mal schneller als die erste Fassung (213 ms) |
| Was wir weggelassen haben | Keine POSIX-Schicht, kein Kompatibilitätscode, keine Kompression im Dateisystem (LZ4 gemessen und gestrichen), keine 3D-Effekte; im VP9-Decoder SIMD-Schleifenfilter und SIMD-Bewegungsausgleich gemessen und wieder entfernt (10.11.). | LZ4: entpacken 600–1200 MB/s (eigener Codec, ein Kern); SIMD-Schleifenfilter 12–15 % langsamer, SIMD-Bewegungsausgleich ohne Unterschied (Mac) | Eine schnelle SSD liest 3- bis 10-mal schneller, als LZ4 entpacken kann – Kompression hätte gebremst. Was nichts bringt, fliegt raus. |
Alle Vergleiche mit „vorher“ sind eigene Messungen derselben Maschine (Handbuch Kapitel 6, Abschnitte 3.93 und 3.137, F142, F143, docs/benchmarks/video-playback.md, network-download.md). Schätzungen beruhen auf Bauart-Unterschieden (Zahl der Schreibvorgänge, Flushes, Kopien) aus docs/database-concept.md Abschnitte 5 und 9 und docs/decisions.md; auf echter Hardware sind sie noch zu bestätigen.
14Grenzwerte
Feste Grenzen aus dem Code (geprüft am 08.11.2026 für Kanäle, TCP, Fenster, Prozessplätze, Menüs; am 10.11.2026 für Dokumenttypen, Capabilities, TCP-Empfangspuffer und Datei-Dialog) und aus der Grenzen-Übersicht des Handbuchs (Stand 05.11.2026). Die meisten sind Konstanten und lassen sich anheben, wenn ein Anwendungsfall es verlangt.
| Grenze | Wert |
|---|---|
| Prozessor | |
| Architektur | AArch64, nur 64 Bit; 16-KiB-Granule Pflicht |
| Kerne | ≤ 8 CPUs; letzter Kern = Echtzeitkern |
| Kernel-Threads | ≤ 64 |
| Arbeitsspeicher | |
| Verwalteter RAM | ≤ 16 GiB (VM-Vorgabe 4 GiB) |
| Seite / größter Block | 16 KiB / 32 MiB |
| Heap je Programm | Vorgabe 256 MiB, memory = 16 … 2048 MiB; ≈ 800 MiB RAM-Heap (32 Stücke) |
| Systemreserve / Spitzen-Polster | 256 MiB / ≈ 3 % des RAM (64 MiB … 1 GiB) |
| Eigener Auslagerungsbereich | 2 × Zusage, höchstens 4 GiB |
| App-Stack | 64 KiB Vorgabe, stack = 64 … 8192 KiB |
| Platte | |
| Partitionen | EFI 64 MiB · SYSTEM_A 2 GiB · SYSTEM_B 2 GiB · DATA Rest (GPT, 1-MiB-Ausrichtung) |
| Größtes DATA-Volume | ≈ 1,99 TiB (1024 Kartenblöcke × 130 560 Blöcke) |
| Name / Pfad | 80 Bytes UTF-8 / 255 Bytes, 32 Teile |
| Offene Dateien | 64 im System, 16 je Programm; 16 KiB je Lese-/Schreibaufruf |
| Block-Cache | DATA 32 MiB, Systemvolume 512 KiB |
| Snapshots | alle 15 min, 24 h / 7 d / 30 d, höchstens 400 |
| Programme | |
| Gleichzeitig laufend | 31 (32 Prozessplätze, Platz 0 = Kernel) |
| Programmdatei | ≤ 32 MiB ELF, ≤ 8 Segmente; Programm-Cache 32 Einträge |
| Worker-Threads | 3 je Programm (+ Hauptthread) |
| Fenster (Zeichenflächen) | 3 je Programm, 16 im System |
| Menüs | 6 Menütitel und 64 Einträge je Fenster; Dock: 6 angeheftet |
| Dokumenttypen (opens =) | 16 Endungen je Programm (seit 07.11.2026, vorher 8); der Kernel kennt 24 Typen (10.11.2026: + Reflex script) |
| Echtzeit-Vertrag | Periode 100 µs … 1 s, Auslastung ≤ 900 ‰ je Kern |
| Capabilities | 32 von 64 Bits belegt (10.11.2026: + files.dialog) |
| Datei-Dialog | ≤ 16 Freigaben je Programm (solange es läuft), ≤ 3 Dialoge gleichzeitig, eine offene Frage je Programm |
| IPC | |
| Kanäle | 16 im System (08.11.2026 von 8 angehoben) |
| Systemaufrufe | 14 Nummern (0–13), Obergrenze 100 |
| Veröffentlichungen | 16 im System, 1 je Programm, ≤ 2 Abos |
| Netzwerk | |
| TCP-Verbindungen | 64 im System (Hälfte davon für eingehende); Empfangsring 128 KiB je Verbindung, ab 1 MiB Empfang einer von 4 Ringen zu 1 MiB (Fensterskalierung 4, seit 10.11.2026) |
| Lauscher | 8; Warteschlange 16, 16 halb offene je Lauscher |
| UDP-Sockets | 4 im System, 1472 Bytes je Datagramm |
| TLS-Verbindungen | 4 je Programm (+ 1 für DNS über HTTPS) |
| DNS-Cache | 64 Namen je Programm |
| Datenbank | |
| Tabellen / Felder | 64 je Datenbank / 64 je Tabelle |
| Datensatz | ≤ 4096 Bytes (alle Felder); große Daten als Datei |
| Transaktion | ≤ 4 MiB |
| Zeilen je Abfrage-Aufruf | 256 (Ausgabe ≤ 256 KiB, danach Cursor) |
| Sortieren ohne Index | Top-N ≤ 1000 |
| Offene Datenbanken | 4 je Programm, 32 im System |
| Joins | 2 für WHERE/ORDER BY, 4 zum Anzeigen; Sortieren nach verknüpftem Feld mit LIMIT ≤ 1000 |
| Aufnahme-Ringe | 16 im System, 1 … 600 s, ≤ 32 MiB |
| Geräte | |
| USB-Klassen | Erlaubnisliste HID, CDC-ACM, UVC, signierte Herstellertreiber; gebaut: HID |
| Kameras | 4 gleichzeitig |
| Grafik | |
| Bildschirm | ≤ 8192 × 8192 (virtio-gpu); VM 1280 × 800 |
| Bilder | ≤ 2048 × 2048 Pixel, ≤ 16 MiB je Datei |
| Datei ≤ 256 MiB, Strom ≤ 64 MiB entpackt, Verschachtelung ≤ 32; Vorschau in Files bis 32 MiB | |
| Video | Aufnahme in Teilen zu 2 GB, Ende bei weniger als 2 GB freiem Platz; ≤ 4 Mio. Bilder je Datei; VP9 ≤ 8192 × 8192; Download aus Web ≤ 64 MiB, ≤ 10 min |
| Mikrofon | Ring ≈ 1,4 s je Mikrofon, 48 kHz, 16 Bit; Pegel alle 10 ms |
| Sicherheit | |
| Passwort | 8 … 64 Zeichen; Argon2id 64 MiB, 3 Durchläufe |
| Bildschirmsperre | 1 … 1440 min oder aus (Vorgabe 5) |
| System | |
| Boot bis „Hello“ | ≤ 1,0 s in SOFTrobotsVM (Testpflicht); QEMU ≤ 10 s |
| Absturzberichte / Logs | 20 Dateien / die letzten 10 Starts, je 1 MiB |