Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Overview (plain English)

Core principles drive ctos. Track A / Track B / A9 are subordinate and never override this list for speed or marketing. Full list: principles.md.

  • Honesty ledger — Verified only with a probe
  • Antifragility — fail-closed sensors + ratchets
  • Security — threat model; probed mitigations only
  • Performance — measure first; no invented benches
  • Document-first / one milestone → one PR

ctos is a learning AArch64 kernel for QEMU virt. It is not a desktop, not POSIX, and not a “secure OS.” Status words need a probe in the honesty ledger. This note does not invent latency, size, or “faster than” numbers. Measured markers live in the ledger; they are one environment each.

Vision: product-vision.md. Pillars: pillars.md. Frozen IDs: fr-nfr.md. Samples: apps-today.md. Porting: building-or-porting.md. Immutability: immutability.md (scoped only). Tracks: A / B / N (subordinate; N1 ADR-066, N2 ADR-067, N3 ADR-070, N3.x ADR-071, N4 ADR-068, N5 ADR-074).

Site chapters (source of truth for the published book): Overview. HTTPS at https://ctos.artof.link is Verified (2026-09-11 after #30). See website.md.

KPIs (what we actually measure)

These are sensors, not product SLOs. A missing marker is a fail. A printed number is not a budget.

Performance (NFR-07 / performance.md)

What we watchProbe (do not invent a target)
Physical counter movesSerial perf: cntpct delta=<n> + #[test_case]
IRQ-to-handler spread on this virt guestSerial perf: irq-delta min=… max=… spread=… n=…
Debug ELF byte sizeHost perf: elf-size bytes=<n> (measurement, not “smaller is better”)
kernel_main after-MMU → after-initSerial perf: boot-delta ticks=<n>
App-load after OS/app split (A9)Verified when ledger has perf: app-load (+ ADR-046 / ADR-051 pairs). Not a published bench.

QEMU TCG jitter is one lab. These are not Raspberry Pi numbers and not a published bench. Read the ledger row for the SHA you care about. A9 expected costs (boot/load, SVC, ASID/TTBR, later COW) vs steady EL0 compute: performance.md. No Verified delta — still one ELF.

Antifragility (NFR-05 / antifragility.md)

What we watchProbe
Hello + milestone strings still printscripts/qemu-smoke.sh greps; missing string → fail
Tests stay fail-closedcargo test exit 0; --features force-fail must be non-zero
Same failure twiceBecomes a sensor/gate, not another README paragraph
Failed history keptExample: Docker b2bbb99 Failed, then layout fix Verified — the Failed row stays

Unprobed boot stays Unknown. File presence is not QEMU boot.

Application-support scope

Do not say “applications run on ctos.” First-class samples and the cannot-run list live in apps-today.md. Porting stance: building-or-porting.md.

  • Can run (probed): coop EL1 UART workers (sched: task a/b/ok); one-byte UART RX (input: rx 0x41); standing EL0 stub (el0: standing / el0: restored); a loaded libctos hello as a standing task until exit (el0: task-ok). A heartbeat/counter variant is the same shape — not in tree until a probe greps it.
  • Cannot run: Linux ELF, shell, Python, network servers (Track N is ARP+ICMP+UDP + tiny EL0 net/UDP SVC samples — not sockets), POSIX disk apps, SMP, a POSIX-style userspace. “EL0 isolated” is Verified only as the accepted ADR-091 sentence (one core, TCG default smoke machine; limits there); PAN is enabled on default cortex-a76 (ADR-080). Identity .data/heap/leftover-RAM tears are ADR-037/038/049. Filesystem stance: filesystem.md (memfs + FAT16 read/write). Gaps to host apps + containers: non-goal: host-apps.md.

Building or porting

First-class page: building-or-porting.md. Short honesty:

  • Easiest = in-tree no_std coop EL1 on aarch64-ctos.json, proven with cargo / qemu-smoke / docker-smoke.
  • POSIX / glibc = not easy, not started.
  • SVC ABI + libctos + guest PT_LOAD + standing-as-normal for freestanding EL0 = A1 ABI + A2 CRT + A3 loader + A4 standing-task miles (dual-SVC stub still exists; not a syscall table; not isolation).

OS image vs app payloads (A9)

The sponsor goal for “immutability” here is not a frozen kernel. It is to disconnect OS updates from apps: one OS image artifact, separate app payloads, so you can replace the kernel without rebuilding apps and replace apps without rebuilding the kernel.

  • First cut + leftover: two host artifacts (target/aarch64-ctos/debug/ctos + target/hello-libctos.elf) and a FAT16 /hello load path (ADR-030, ADR-032, A9 #48). A2–A4 load that file. Stance: immutability.md.
  • Cross-update: same app ELF on this OS and documented prior OS ba6541c. Product freestanding app hosting is Verified under ADR-048/052. Do not say OTA / “immutable OS” marketing / Linux hosting.
  • Do not say “immutable OS.”
  • Performance: perf: app-load measures the FAT load path; ADR-046 adds probe-only perf: embed-load + perf: slot-delta (QEMU TCG lab pair — not a percent). ADR-051 adds perf: fat-write / perf: memfs-write / perf: fs-write-delta (same-boot write pair — not a percent). Expected costs: boot/load, SVC, ASID/TTBR, optional later COW. Details: performance.md.

Prerequisites

  • Nightly Rust (rust-toolchain.toml), rust-src, llvm-tools-preview
  • qemu-system-aarch64 (Debian package is often qemu-system-arm)
  • Optional: Docker linux/arm64 (./scripts/docker-smoke.sh) — do not pin linux/amd64
  • To change the kernel: one milestone → one branch → one GitHub PR; author ≠ merger (ADR-002)

A machine that has not run scripts/qemu-smoke.sh (or Docker/GHA equivalent) has Unknown boot.

Advantages

  • Small, readable no_std tree on one ISA (AArch64 / QEMU virt / PL011 UART)
  • Fail-closed smoke: serial markers, cargo test, force-fail
  • Honesty ledger: Verified / Unknown / Planned / Failed, with a probe each
  • Failures become sensors (layout miss, live-.text vtable yank, CRLF shebang)
  • Three pillars named up front — security and speed still need probes

Drawbacks

  • QEMU virt only. No Raspberry Pi or board claim
  • Not POSIX, not multi-tenant, not a product runtime. memfs + FAT16 read/write (filesystem.md; ADR-050). Not a container host (non-goal, ADR-029); host docker-smoke ≠ guest Docker.
  • Umbrella “EL0 isolated” is Verified only as the accepted ADR-091 sentence (M6; history ADR-047). Live identity .text / .rodata / .data / heap / leftover RAM are torn (ADR-020/025/037/038/049); _start stays; PAN is enabled on the default -cpu cortex-a76 (ADR-080; historical a57 pan: absent)
  • Scoped immutability only (immutability.md): RO+NX / WXN / live .text tear are probed. Absolute “immutable OS” is incompatible (heap/PTEs/devices must mutate). OS/app slot first cut (A9 / ADR-030) is two artifacts + FAT /hello. Leftover (ADR-032): A2–A4 load FAT; same ELF on this OS and ba6541c.
  • Performance numbers are guest counter deltas, not a latency budget
  • Docs website / custom domain: HTTPS serving the book is Verified (website.md)
  • Same-login cannot self-merge; a second identity has to land the PR

Honesty

Do not say “secure OS,” “the kernel moved,” “immutable OS,” or “apps update independently of the OS.” Point at the ledger for any number you quote. Say “EL0 isolated” only as the accepted ADR-091 sentence, never wider. The live docs URL is a separate Verified row — do not invent other site claims.