rowan.id.au— Piers Rowan

HomePiROS › GLOSSARY.md

PiROS glossary

Terms as they're used in PiROS, with the general meaning and — where PiROS deviates — a one-line Drift note on why. Alphabetical. Constants (with their values and why they're set low) are gathered at the end.


A + B = C — PiROS's core thesis: a program runs only if (A) the exact bytes match (B) what an authority signed, producing (C) a verified certificate. General: code-signing / attestation. Drift: PiROS makes it the gate on every execution, not just install.

address space — the set of virtual→physical memory mappings a process sees; in PiROS, one page table per process (kernel half shared, user half private). General: same. Switching one is a CR3 write.

alloc — Rust's alloc crate (Vec, String, Box, format!) — dynamic heap allocation. General: same. In PiROS it works in ring-3 programs via a global allocator (LockedHeap) over the mapped user heap; the kernel has no heap (it uses fixed static arrays). Drift: using alloc in a program is a deliberate "capability" choice (e.g. the SQL engine), not the default.

AHCI — Advanced Host Controller Interface: the standard for talking to SATA disks. Registers are memory-mapped at ABAR (PCI BAR5); a transfer is a command list + FIS + a PRDT, issued via a per-port register. General: same. hal/ahci.rs implements enough to read/write sectors (polled); it's what persists /data on the appliance's SSD. Behind [[disk (facade)]] alongside legacy IDE.

ARP — Address Resolution Protocol: maps an IP to a MAC on the local link. General: same.

authority (key) — the offline ed25519 keypair that signs the base system (users, grants, programs). Its private half never touches the box. General: a root/CA signing key. Drift: kept strictly offline; the box can verify against the public half but never mint with it.

authorized_keys — a file of SSH public keys allowed to log in. General: OpenSSH's file. PiROS reads per-user files/authorized_keys and the global mnt/authorized_keys.

capability / grant — a signed record saying "user U may run tool/cluster C". General: a capability = an unforgeable token of authority. PiROS grants are ed25519-signed certs; deny-by-default.

charon — PiROS's SSH daemon (port 2222): curve25519 KEX, ed25519 [[host key]], aes128-ctr + HMAC, password and publickey auth, a shell channel. Named for the ferryman (aquatic-authors theme). General: sshd. Drift: kernel-hosted (not a ring-3 program) — it runs each session's shell as the authenticated user; answers SSH keepalives so idle sessions don't drop. A listener task accepts connections and hands each to its own [[session worker]], so sessions run concurrently (no [[head-of-line blocking]]).

cmdlist — the built-in command reference tool. cmdlist lists every tool A–Z; cmdlist <prefix> filters. Data-driven from the read-only mnt/commands.txt, so the list updates without recompiling.

cluster (service) — a named group of tools a grant can authorize together (e.g. core, services, server_tools). General: elsewhere "service" means a daemon; in PiROS a "cluster" is a permission group, and a "service" (below) is the running daemon. Drift: the word "service" is overloaded — the cluster form is the grant namespace.

coalescing (output) — batching many small writes into one packet instead of sending each alone. General: Nagle-style write coalescing. Drift: PiROS's non-interactive ssh <box> '<cmd>' buffers a session's output into a per-task slab (OBUFS) and flushes a packet at a time, because a no-pty client delays its ACKs and one-packet-per-write blocked ~40 ms each. Interactive sessions stay unbuffered so admin upgrade/prano paint live. Replaced the old single global SHELL_OUT.

congestion control (cwnd / ssthresh / Reno) — the sender's self-limit on how much unacked data to keep in flight, so it doesn't overrun the network (distinct from [[flow control]], which respects the receiver). cwnd = congestion window (segments); ssthresh = the slow-start threshold; slow start grows cwnd exponentially until ssthresh, then congestion avoidance grows it linearly. General: standard TCP Reno (RFC 5681). Drift: PiROS's net/tcp_input.rs is a from-Linux port (tcp_cong.c) adapted to the polled, no-interrupt kernel — the actual amount in flight is min(cwnd, snd_wnd), the smaller of the congestion window and the [[flow control]] window.

context switch — pausing one task and resuming another by swapping the stack pointer (rsp)

not timer-driven (yet).

CR3 — the x86 register holding the physical address of the active page table (L4). Writing it switches address spaces. General: same.

disk (facade)hal/disk.rs: one sector interface (read_sector/write_sector) that the VFS talks to, with the concrete backend chosen at probe time ([[AHCI]] → IDE → RAM-only). General: a block-device abstraction. Drift: PiROS-specific seam that keeps the OS from hard-coding one storage chipset — adding NVMe/virtio-blk is implementing this + a probe arm.

DMA — Direct Memory Access: a device reading/writing RAM without the CPU. PiROS reserves a 128 KiB contiguous slab for the NIC's rings + AHCI's command structures. General: same.

dot-file (hidden) — a file or directory whose name starts with . (e.g. .charon/, .psh.conf). ls hides them; ls -v shows them. General: the Unix hidden-file convention. Drift: PiROS uses it for per-user config that shouldn't clutter a normal listing.

encrypt-then-MAC — seal data by encrypting it, then computing a MAC (HMAC) over the ciphertext, so tampering is caught before decryption. General: the preferred AEAD construction. Drift: PiROS uses it in the [[vault]] (ChaCha20 + HMAC-SHA256) and the SSH transport (AES-CTR + HMAC). Both underlying ciphers are malleable streams, so the MAC is the only integrity guard — a bug that MAC'd only part of the message (see [[HMAC]]) silently voided it past that point.

ed25519 / x25519 / curve25519 — the elliptic-curve primitives PiROS implements from scratch: ed25519 = signatures (certs, SSH host key), x25519 = key exchange (SSH), curve25519 = the shared curve. General: standard modern crypto.

ELF — the executable file format PiROS tools compile to; the kernel's loader parses PT_LOAD segments into the program window. General: same.

ephemeral port — a throwaway high-numbered port the client OS picks per outbound connection. General: same. (A common misconception: the server never changes port — see the 4-tuple entry.)

exec_captured — a kernel helper that runs one tool and captures its stdout into a buffer (used by the SSH shell to relay command output). General: like popen/backticks. Drift: not a general subprocess API — it's synchronous and single-buffer; true exec awaits per-process windows.

frame — one 4 KiB page of physical RAM. The unit the kernel allocates. General: "page frame".

frame allocator — hands out physical frames. PiROS bump-allocates from the largest usable RAM region, backed by an intrusive free-list so exited processes' frames are reclaimed and reused.

framebuffer — a linear region of memory where each pixel is a colour value; the GPU scans it out to the display (HDMI/DP/VGA connector — the OS doesn't care which). To show text you render a bitmap font into it yourself. General: same. The bootloader hands PiROS a framebuffer (1280×720, 24-bit BGR); hal/fb.rs is a scrolling text console over it (8×8 font in hal/font.rs, 80×45 cells), mirrored from serial::print so PiROS shows on the attached display. Input (PS/2 keyboard) is next; the same surface later carries a GUI. Contrast [[VGA text mode]].

free-list — a list of freed resources available for reuse. General: standard allocator structure. In PiROS the frame pool uses an intrusive one (a freed frame stores the next free frame's address in its own first bytes — zero extra memory). Sockets are reclaimed per-owning-task.

flow control (advertised window / snd_wnd) — the receiver telling the sender how much buffer space it has, in the TCP header's window field; the sender must not send past it. General: standard TCP flow control (distinct from [[congestion control]], which respects the network). Drift: PiROS ignored this until the TCP port — poll() discarded the header field and send() transmitted regardless of what the receiver could hold. Now tracked as snd_wnd and honoured, so a slow reader throttles the sender instead of dropping data.

4-tuple — (src IP, src port, dst IP, dst port): what uniquely identifies a TCP connection. Many connections share one server port; the tuple tells them apart. General: same.

GDT / TSS — Global Descriptor Table (segment + privilege definitions) and Task State Segment (holds RSP0, the kernel stack the CPU switches to on a ring-3 trap). General: same. PiROS mutates TSS.RSP0 at runtime so each process traps onto its own kernel stack.

grant — see capability.

HAL — Hardware Abstraction Layer: PiROS's hal/ (UART, ATA disk, RTL8139 NIC, PCI). General: same.

head-of-line blocking — a queue where one slow item stalls everything behind it, even though those could proceed. General: the networking/queueing term. Drift: PiROS's original [[charon]] served SSH sessions one at a time (accept → whole session → next accept), so a held-open interactive session blocked every other client until it logged out (they timed out "at auth"). Fixed by giving each connection its own [[session worker]] task. It was not a TCP/ACK problem, despite the name it was first filed under.

HMAC — a keyed message-authentication code (HMAC-SHA256 here): proves a message wasn't altered and came from a holder of the key. General: RFC 2104. Drift: PiROS's is vendored (bare-target, no SIMD) and is the integrity half of every [[encrypt-then-MAC]] seal — the [[vault]] and SSH both verify with it, so it must cover the whole message: a fixed-buffer version that silently truncated at 1024 bytes left the tail of every larger sealed file / SSH packet unauthenticated.

heap — dynamically-allocated memory region. PiROS maps an 8 MiB per-program user heap for alloc. General: same. Drift: the kernel has none (static arrays only).

host key — [[charon]]'s ed25519 server identity; its fingerprint is a client's known_hosts entry. Seed generated (RDRAND) on first boot, persisted on /data at LBA 8192 — past the stores and past the boot image, so a kernel upgrade doesn't wipe it and the fingerprint stays stable across builds. General: an SSH host key. Drift: was at LBA 2048 (inside the boot image) and so churned every build; system state, headed for [[/root]].

IDT / int 0x80 — Interrupt Descriptor Table; int 0x80 is the syscall gate ring-3 programs trap through. General: int 0x80 is the classic Linux syscall vector; PiROS reuses the convention.

kernel stack — the stack the kernel runs on while handling a trap/syscall for a task; each task has its own (so it can be paused mid-syscall). General: same.

KERNEL_RSP — the kernel stack pointer a synchronous tool run returns to when the tool exits (a longjmp target set by enter_user, used by exit). General: PiROS-specific. Drift: it's one global, but the scheduler saves/restores it per task on every switch, so a preempted console/sshd tool keeps its own return point.

Karn's algorithm — the rule that you must not measure [[RTT]] from a segment that was retransmitted (you can't tell if the ACK answered the original or the copy). General: standard TCP. Drift: PiROS's sender drops an RTT sample whose segment it ever retransmitted, so a lost packet can't poison the smoothed RTT / [[RTO]].

KEX — key exchange: the SSH handshake that agrees a session key (curve25519-sha256 in PiROS). Ends with both sides sending NEWKEYS to switch on encryption. General: same.

L4 / paging — x86-64 uses a 4-level page table; L4 is the top. PiROS builds one L4 per process. General: same.

localca — PiROS's on-box "local certificate authority": the machine key + the runtime-minted user/grant store. General: a local CA. Drift: it's a second, lower authority (root-gated) distinct from the offline authority.

machine key — a per-box ed25519 keypair: public half embedded as a trust anchor, seed embedded so an authenticated root can mint records live. General: a device/host key. Drift: PiROS- specific — the runtime counterpart to the offline authority; currently stored in the clear (hardening: encrypt under root's password).

manifest — the signed certificate binding a program's name+version to the SHA-256 of its ELF. General: a signed metadata record. The manifest tool is the offline signer.

mnt — the shared read-only /mnt volume, built from the host mnt/ folder at build time, readable by all users. General: a mount point. Drift: it's a build-baked blob, not a live mounted disk.

no_std — Rust without the standard library (no OS underneath). PiROS's kernel and programs are no_std. General: same.

NX (no-execute) — a page-table bit marking memory as data-only; the CPU faults if it tries to execute there. General: the standard W^X protection. Drift: in PiROS a kernel-stack overflow that clobbers a return address surfaces as an NX fault whose faulting instruction pointer equals the faulting address — the CPU "returned" into the stack. That signature is how the per-connection [[session worker]] overflow was identified (it needed a bigger KSTACK_SIZE than the single sshd).

overlay (/bin) — a writable disk region where installed programs live, shadowing the baked ramdisk. General: a union/overlay filesystem idea, minimal here.

PASV — FTP passive mode: the server opens a second port for the data channel and tells the client. General: same; nemo implements it. (FTP is the rare protocol that really does use a second port — cf. the ephemeral-port misconception.)

PHYS_OFFSET / phys map — the whole of physical RAM mapped at a fixed high virtual offset, so the kernel can reach any frame by phys_offset + phys_addr. General: "direct/physical map".

PoC — proof of concept: proves a thing can work; distinct from an implementation that works reliably under load. General: same.

PS/2 keyboard — the legacy keyboard interface (8042 controller, data port 0x60 / status 0x64). PiROS polls it (no IRQ 1) and maps scancode set 1 → ASCII with Shift + Caps. General: same. On the appliance the USB keyboard is presented as PS/2 by the BIOS's USB-legacy emulation, so this one driver covers it without a USB stack. It's the [[framebuffer]] console's input half.

PIC / PIT — the legacy 8259 interrupt controller and 8254 programmable interval timer. PiROS remaps the PIC to vectors 32-47 and runs the PIT at ~100 Hz to drive preemption. General: same.

preemption — the scheduler forcibly interrupting a running task (via a timer) to run another. General: same. Drift: PiROS preempts all ring-3 code (any tool or process) but keeps the kernel interrupt-free (IF=0) — the PIT fires solely while user code runs. So a runaway can't hang the box (and can still be reaped), yet kernel code holding a lock is never interrupted. Safe because each task carries its own [[trap stack]] + saved copies of the KERNEL_RSP/sink globals.

process / task — a scheduled unit. In PiROS a task is a scheduler slot; a process is a task with its own address space (a ring-3 program). Task 0 = the console; kernel services (sshd) are kernel tasks; tintin/nemo/queequeg are processes. General: "process" implies its own memory.

ps — lists scheduler tasks + resources. General: the Unix process lister.

ramdisk — the immutable, signed /bin image the bootloader hands the kernel; tools load from it. General: a RAM-backed disk.

RDRAND — an x86 instruction returning hardware randomness; PiROS uses it to seed ephemeral SSH keys (refuses weak keys if absent). General: same. (Also used by the rand_test demo tool, which prints a 32-char random value straight from ring-3 — RDRAND is unprivileged, so it needs no syscall.)

RDTSC / monotonic clockRDTSC reads the CPU's cycle counter; it runs regardless of IF (interrupt flag). General: the standard fine-grained timestamp. Drift: it is PiROS's only usable clock inside the kernel, because the [[PIC / PIT]] tick counter only advances while ring-3 code runs (the kernel holds IF=0) and is frozen during a kernel-side spin — useless for measuring an [[RTT]]. hal/tsc.rs calibrates RDTSC→microseconds once against PIT channel 2 (polled, no interrupt) to give a monotonic now_us().

redirect (> / >>) — shell output redirection into a file. General: same. Drift: PiROS's is quote-less and only targets files/; > inside HTML can misfire (use prano).

retransmit (RTO / fast retransmit / go-back-N) — resending data the peer didn't ACK. RTO = retransmission timeout, the wait before resending on silence, derived from the measured [[RTT]] (SRTT + 4·RTTVAR, RFC 6298) with exponential backoff. Fast retransmit = resend immediately on 3 duplicate ACKs instead of waiting for the RTO (the pipe is alive, one segment was lost). Go-back-N = on loss, rewind and resend from the first unacked byte. General: standard TCP. Drift: PiROS's sender does all three ([[congestion control]] halves cwnd on a fast retransmit, collapses to 1 on an RTO); loss recovery is go-back-N because there's no SACK.

RTT / SRTT / RTO — round-trip time: how long a segment→ACK takes. SRTT is the smoothed (Jacobson/Karels) estimate; RTO (above) is derived from it. General: standard. Drift: PiROS measures RTT with the [[RDTSC / monotonic clock]] and samples per [[Karn's algorithm]]; the whole estimator is ported from Linux (tcp_input.c) into net/tcp_input.rs, preserving its fixed-point scaling.

RES tick — a syslog line tagged RES tick: — an automatic resource snapshot (free frames, sockets, tasks) emitted from the scheduler, only when a number changed, so the log shows trends without flooding. General: PiROS-specific (a throttled telemetry sample).

ring 0 / ring 3 — x86 privilege levels: ring 0 = kernel (full access), ring 3 = user (restricted). PiROS tools run in ring 3; the only path up is the syscall trap. General: same.

recovery key — a one-time break-glass token minted (RDRAND) when /data is first provisioned, shown once at the login banner (store it offline); its SHA-256 is kept in the superblock. recover <64-hex-key> at the login prompt verifies it and resets root's password. General: a disk- encryption / account recovery key. Drift: replaces a universal default password — each box has its own, held by its own operator; can't lock the owner out.

/root (region) — planned tier-2 store for system state (host key, [[vault secret]], recovery hash, password deltas), separate from userland /data and root-only. General: Unix /root is root's home; here it's the machine-state partition. Drift: the overlay model — the immutable OS holds secure defaults, /root holds the deltas, so a wiped /root still boots securely.

scheduler — decides which task runs. PiROS's is a cooperative round-robin (sched.rs). General: same; production schedulers preempt.

service — a root-managed background daemon (admin service start/stop). tintin/nemo/queequeg are sandboxed ring-3 processes (each a no-login service user); [[charon]] is a privileged kernel- hosted service. A service identity has an all-zero password hash (no password can match it), built directly with no PBKDF2 — so creating one is instant. General: a daemon. Drift: "service" (daemon) vs "cluster/service" (grant group) are different things sharing the word.

session worker (per-connection task) — a scheduler task that runs one SSH session end-to-end, so [[charon]]'s listener can accept the next client immediately. General: the one-thread-per- connection server model. Drift: PiROS-specific — the listener accepts, then spawn_args a worker handed the socket (task_arg) and transfers ownership (tcp::set_owner); the worker builds its Transport on its own kernel stack, so the per-task session state (INTER/OBUFS (see [[sink]])) is valid for exactly that session. Bounded by [[MAX_TASKS]] (table full → the client is refused with a one-line hint, never silently dropped). This is what removed [[head-of-line blocking]].

setjmp/longjmp — save/restore a call-site so you can jump back to it non-locally; PiROS's original single-process ring-3 exit used this pattern. General: same (C idiom).

sink (serial sink) — a mode where console output is captured into a buffer instead of the UART (used by exec_captured). General: an output redirection buffer. Drift: the capture buffer is one global (one capture at a time — fine for a single SSH session), but the "am I capturing" flag is saved/restored per task on a switch, so a preempted capture can't swallow another task's output.

socket — a TCP endpoint (a slot in the kernel's socket table). General: same.

spawn / spawn_program / spawn_arg — start a new scheduled task. spawn = a kernel task; spawn_program = a ring-3 process (own address space + kernel stack + trampoline); spawn_arg = a kernel task handed one word of argument, read back inside it via task_arg() (reusing the Task.info slot). General: spawn starts a thread/process; PiROS has no fork (spawn is cleaner for our needs). Drift: spawn_arg exists so [[charon]]'s listener can hand each [[session worker]] its accepted socket handle — spawn alone takes a bare fn with no parameter.

syscall / SYS_* — the trap-based kernel API; SYS_ are the numbered call IDs in pros-abi. General:* same.

syslog — PiROS's always-on in-kernel ring buffer of events (spawns, exits, faults) + RES snapshots; syslog (root) dumps it. General: Unix syslog is a userspace logging daemon. Drift: PiROS's is an in-kernel ring buffer (kernel-authored, survives until viewed), not a userland service — it captures kernel-level events a ring-3 logger couldn't see.

TCP — the reliable stream transport PiROS implements from scratch (handshake, seq/ack, [[retransmit]]). General: same; PiROS's is a pragmatic subset (polled, simplified teardown, no SACK / window-scaling / timestamps). Drift: the sender is no longer stop-and-wait — it honours the peer's window ([[flow control]]), runs a Reno [[congestion control]] window, and retransmits on a measured [[RTO]] with fast [[retransmit]]. The send-side control algorithms are ported from Linux into net/tcp_input.rs (which makes that file, and the kernel, GPL-2.0).

trampoline — the tiny function a freshly-spawned process's kernel stack is pre-loaded to run on its first switch-in: it sets CR3 + TSS.RSP0 and drops to ring 3. General: a small stub that bridges into a different context.

trap stack (RSP0) — the kernel stack the CPU switches to when ring-3 code traps (syscall, timer, fault) — the RSP0 field of the [[GDT / TSS]]. Drift: PiROS gives each task its own, so preempting one task's tool run can't scribble on another's kernel frames. A process reuses its own kstack (abandoned on exit); a kernel task that runs tools (sshd) gets a dedicated one; the console uses the boot privileged stack.

VBE (VESA BIOS Extensions) — the BIOS-era standard for setting a graphics mode + getting a [[framebuffer]] address. The bootloader uses it to hand PiROS a framebuffer, so PiROS needs no GPU driver for basic pixel output. General: same. (The UEFI equivalent is GOP, the Graphics Output Protocol — not relevant to us since we boot BIOS.)

VGA — heavily overloaded. (1) the blue D-sub connector — irrelevant to the OS, which just draws pixels the GPU scans to whatever port. (2) VGA text mode — a legacy 80×25 mode where you write ASCII+attribute bytes to 0xB8000 and the hardware renders characters. Simple, but a dead end: modern GPUs/HDMI often don't support it, and you can't build a GUI in it. PiROS uses a [[framebuffer]] instead (raw pixels you render), which works over HDMI and scales to a GUI. Drift: PiROS deliberately avoids VGA text mode.

vault — PiROS's per-user authenticated encryption (ChaCha20 + HMAC-SHA256 (see [[HMAC]]), [[encrypt-then-MAC]]) sealing every file before disk. General: an encrypted store. Drift: each key is HMAC-keyed by a per-instance [[vault secret]] and the user index, so one box's /data cannot be decrypted by another (or by a user peeking at raw bytes); deriving from the login password is a further step.

vault secret — a 32-byte random value minted from RDRAND on the first /data format, stored in the superblock, keyed into every [[vault]] key. General: a per-device data-encryption key. Drift: it lives on /data today (cross-server isolation); moving it to the root-only [[/root]] region adds stolen-disk protection. Lost secret (wiped /data) = unreadable data, by design.

vfs — the virtual filesystem: per-user encrypted stores with a directory tree (files/logs/tmp), plus special dirs (mnt, services/<svc>). General: same.

window (program window) — the fixed 2 MiB virtual region (0x4000_0000) every tool is linked to load at; per-process it's backed by different physical frames. General: PiROS-specific term for the executable user region.

yield / yield_now — voluntarily hand the CPU to the next ready task. General: cooperative yield. PiROS's blocking syscalls (accept/recv/getc) call it so servers give up the CPU when idle.


Constants — and why they're set low

PiROS caps are deliberately small. The reason is almost never "we're short on RAM" (we have ~88 MiB free at boot) — it's that these are statically allocated fixed arrays in the kernel (no kernel heap), and each entry is heavy, so scaling multiplies memory. Keeping them lean also keeps the code branch-simple. Raising any is a one-line change once a workload needs it; growing them dynamically would need a kernel heap (a deliberate later step).

ConstantValuePer-entry costWhy this low
MAX_USERS16a Store ≈ 200 KiB (encrypted node/data pool)16 × 200 KiB ≈ 3.2 MiB of static BSS; plenty for root/bob/mary + services + a few users
MAX_TASKS8a KSTACK_SIZE kernel stack8 tasks; console + a handful of services + concurrent SSH [[session worker]]s. Each session takes a slot, so this also caps concurrent SSH
KSTACK_SIZE128 KiBa session task runs the deep synchronous shell→tool chain; 16 KiB faulted, and a per-connection worker overflowed 128 KiB (headed for 192 KiB pending review — a release build would shrink frames back under 128)
MAX_SOCKETS32RX/TX buffers (48 KiB RX each)users × services + inbound/outbound headroom; bounded so a leak is visible, not silent
MAX_MEMBERS3232 B name eacha cluster's tool list; core grew past 20
MAX_NODES / MAX_DATA / MAX_ENTRIES (vfs)96 / 48 / 16node/data blocks per user storedirs+files, file blocks, children-per-dir — sized for a demo tree
DATA_CAP4096max file size today; the read-to-memory model scans whole files
PROGRAM_BYTES2 MiBper processthe executable window; tools are small
HEAP_SIZE8 MiBper processgenerous alloc heap; multiplies per spawned process
syslog MAX_LINES25692 B/linea rolling window of recent events (~23 KiB)

Policy for now: keep them lean (code efficiency over laziness). When a real workload hits a cap, the fix is either bump the constant (cheap, RAM is available) or make that specific resource heap-backed/dynamic — decided per resource, not blanket.