One GPT stick that is the whole OS: ESP, a StarshipOS identity partition and a StarshipOS Artemis partition; a splash until Zuse logs in, automatically; each stick mints its own Zuse on first boot; try-it writes persist on the stick until INSTALL; pulling it goes headless. GPT comes back for boot media and installed disks (overturns FABRIC-2.md F.8 for those); system=v3 is refused on a stick; every clean qemu boot uses a GPT data stick over USB, virtio Artemis leaves v4. Approved by Captain Bob 2026-10-26. First of three designs (then INSTALL, then DOE/SDK/demos); ahead of ENGINE step 4 Part A. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
16 KiB
StarForth v4.0.0 — The x86_64 StarshipOS stick
Design, 2026-10-26, from Captain Bob's answers the same day (each quoted where it is used). The
first of three designs toward the goal below; the other two, INSTALL and DOE/SDK/demos, are
written after this one is approved.
1. Intent
"the goal is to be able to deliver an entirely self hosted thumbdrive
buildthat can deliver the entire OS for x86_ 64 asap." (Captain Bob, 2026-10-26)
"we want a functional
try itimage with INSTALL should users decide to install StarshipOS in their bare metal."
One USB stick, written from one image, that a person plugs into an x86_64 PC and boots from the
firmware's boot menu. It is the whole operating system: StarshipOS on LithosAnanke, running v4
("v4 only"). Until the person installs, it is a "try it" — like Ubuntu's — that leaves the PC's
own disk untouched. Installing is a later design (INSTALL); after it, the stick is Zuse's key.
Ordering (ruled): "stick first, then Part A" — this goes ahead of ENGINE step 4 Part A. Three
designs, in this order: (1) the stick, this file; (2) INSTALL; (3) S" <doe name>" DOE, SDK
and demos.
2. What the person sees
- They boot the stick from the PC's firmware boot menu.
- The screen shows only the StarshipOS splash with a progress bar ("splash only, log on serial"). The whole boot log goes to the serial port, if there is one.
- First boot of a stick: the kernel finds no Zuse on it and mints one — "minted on first boot, each stick its own Zuse."
- Every boot: the kernel recognises Zuse on the stick and logs her in by itself —
"automatic, like v3 does when the drive is attached." The splash gives way to the console:
[zuse@Hera] ok>, typed to with the PC's USB or PS/2 keyboard. - While they try it, what they write persists on the stick across reboots — "persist on the stick until INSTALL." Nothing is written to the PC's own disk.
- If they pull the stick mid-session: "go headless until it's plugged back in." The console goes; the splash comes back; plugging the stick in again logs Zuse in again.
3. Rulings this design rests on
| Ruling (2026-10-26) | Where |
|---|---|
| Boot to a headless splash until Zuse logs in | §2 |
| Zuse's identity is on the same stick that boots | §4 |
| Zuse logs in automatically, as v3 does when her drive is attached | §5 |
| Each stick mints its own Zuse on first boot | §6 |
What a try-it session writes persists on the stick until INSTALL |
§4, §7 |
| Splash only on screen; the log on serial | §8 |
| Pulling the stick: headless until it is plugged back in | §7 |
GPT for boot media and installed disks — overturns FABRIC-2.md §F.8 ("GPT dropped entirely") for these two kinds of media; raw identity drives stay accepted |
§4 |
| v4 only | §1 |
On the stick, system=v3 is refused: a line says v3 is not on this stick, and v4 boots |
§5 |
The GPT code runs on every ISA; every clean qemu boot attaches a small GPT data stick (identity and Artemis partitions) over USB in place of virtio; virtio Artemis leaves v4 |
§9 |
| The splash: a PNG-only converter now, the general converter interface later; scaled at build to 1024×683; its capsule ID is the hash of the converted pixels | §8 |
| QEMU and bare metal ALWAYS hold parity (standing rule) | §9 |
4. The stick's layout
A GPT disk, written from one image built by make boot_image TARGET=PC (scripts/mkdiskimage.sh
gains the partitions below). Three partitions:
| # | Partition | GPT type | Contents |
|---|---|---|---|
| 1 | EFI System (FAT32) | EFI System (C12A7328-…) |
the loader BOOTX64.EFI, starforth.cfg (system=v4), startup.nsh — as today's PC image |
| 2 | StarshipOS identity | a StarshipOS identity type GUID (new) | blank in the image; on first boot, Zuse's identity in today's home-blocks layout (homeblocks_sig.h: signature at devblock 1, identity record, cert), counted from the partition's start |
| 3 | StarshipOS Artemis | a StarshipOS Artemis type GUID (new) | today's Artemis disk layout (STFR volume header, artemis_sig_t genesis signature, the metadata fence holding Zuse's genesis marker), counted from the partition's start |
- The kernel reads GPT (new: a GPT reader, on every ISA, used again by
INSTALL). It reads the primary GPT header and entries (checking their CRC-32s) and makes a block device of each partition whose type is one of the two StarshipOS types: a thinblkiodevice that adds the partition's start to every block number and refuses blocks past its end. - Which disk (my call). Zuse and Artemis are taken from one disk: the stick the PC booted
from. The UEFI loader already knows its boot device; it passes it to the kernel (
BootInfo), and the kernel takes the USB disk that matches it. Both StarshipOS partitions must be on that disk. A second stick, or a blank drive the person happens to have plugged in, is not used: no Zuse is minted onto it and it is not attached to the block subsystem. (So pulling the stick is never refused for a drive attached after it —blk_subsys_detach_deviceremoves only the last device in the chain — and on replug Artemis is the first disk slot again, where the fence with Zuse's marker must be.) In QEMU, with no boot device among the USB disks (theclean qemuboots start from the ISO or the ESP image), the data stick (§9) is the one disk with both partition types; the rule is the same: one disk carries both. - The identity and Artemis formats do not change. Every check that reads them
(
homeblocks_sig_check,capsule_zuse_boot_check,artemis_sig_check, the block subsystem) runs unchanged on the partition device. - Raw identity drives stay accepted: a device with no valid GPT is read as today (the minted
scratch pair in
disk/zuse-scratch/, any v3 identity drive). - Sizes (my call): the image is a fixed size and does not grow to fill a bigger stick.
Partition sizes are set at build time: ESP 64 MiB, identity 64 MiB (today's identity drive
size), Artemis the rest of a 2 GiB image. Changeable in one place,
kernel/Makefile. - The Artemis partition is formatted when the image is built (my call), not on first boot:
the image builder writes its
STFRvolume header and itsartemis_sig_tgenesis signature, so the kernel never meets a blank Artemis on a stick and never has to decide whether a disk may be formatted. (v4's rule that the boot writes no disk until its owner says so —kernel_main.c,sk_v4_block_chain's comment; ENGINE step 4 Phase 5 — is met: the stick's Artemis partition was made to be written, by the image's maker. The kernel confirms the format (blk_subsys_confirm_format) only for a partition whose GPT type is StarshipOS Artemis and whoseartemis_sig_tchecks out.)
5. Boot
Everything the identity gate does today (kernel/src/v4/sk_v4_identity.c), with five changes:
- Where the disks are found. After POST, the kernel brings up every xHCI controller (as now) and, for the boot stick, reads its GPT: the Artemis partition is attached to the block subsystem as Artemis's disk (the first disk slot, so the metadata fence — Zuse's genesis marker — is on it), and the identity partition is checked as an identity drive. The virtio disk is no longer how v4 finds Artemis, in QEMU or anywhere (§9).
- Entropy.
rng_init()is called on the v4 path (it is not today); on x86_64 the backend is RDRAND (kernel/src/rng/rng.c). Minting needs it. On aarch64 and riscv64 theclean qemuboots mint with virtio-rng, the only backend those ISAs have (BRINGUP.mdA5): a known QEMU-only path, which their own sticks (later) must replace with real hardware entropy. - The screen. The framebuffer is brought up on the v4 path, as v3 does (
console_fb_init,kernel_main.cv3 path), but the console's text goes to serial only until Zuse logs in; the screen shows the splash (§8). When she logs in, the screen becomes the console. - The keyboard. The USB and PS/2 keyboard bridge v3's console reads (
repl.c:sk_kbd_getc,sk_console_getc_raw, the per-tick xHCI servicing while a USB keyboard runs) is moved out ofrepl.cinto a file both paths use, unchanged in behaviour, and the v4 line editor reads it as well as serial. system=v3is refused on the stick (ruled). The stick's kernel carries v3 too, and v3 has no GPT reader: it would see the whole stick as one raw drive and its genesis could mint over the partition table. So when the boot medium is a StarshipOS stick (a GPT disk with the two StarshipOS partition types),system=v3is not obeyed: "System: v3 is not on this stick -- StarForth v4", and v4 boots.
6. First boot: genesis on the stick
On the first boot of a stick, the identity partition is blank and the Artemis partition's fence
has no genesis marker: capsule_zuse_boot_check says ZUSE_DRIVE_GENESIS. The kernel then does
what v3's genesis does (capsule_zuse_boot_try_attach), with no VM:
capsule_mint_identity(dev, NULL, "Zuse", "zuse", …) mints her onto the identity partition, and
the genesis marker (her public key) is written to the Artemis partition's fence
(blk_meta_zone_write(0, …)). "Zuse: genesis minted onto attached thumbdrive"; she is logged in.
- This lifts the identity gate's D2 ("recognise only") for the stick: genesis is allowed where
the Artemis disk is one the kernel was given to write (§4). A blank Artemis that is not a
stick's partition — QEMU's old blank
disk/artemis.img, an unknown disk — still gets no genesis. - The genesis is shared code: the VM-free part of v3's genesis (mint, then marker) is split out
of
capsule_zuse_boot_try_attachascapsule_zuse_boot_checkwas (D1), and both paths call it. - If the mint fails (no entropy, a write error): "Zuse: genesis mint failed", and the system stays headless behind the splash. Nothing half-written is taken for an identity.
7. A session, and pulling the stick
- Writes persist on the stick — the Artemis partition — and nowhere else. The idle beat
writes the node's updated blocks about once a second, as v3's does (
blk_vm_flush_allinsk_repl_idleis the same code asSAVE-BUFFERS) (my call, for v3 parity): on v4 it is the kernel saving the node's block window's updated slots, at the prompt or while headless, never mid-line. - Pulling the stick detaches both its partitions. Zuse's session ends ("Zuse: session ended -- reattach to re-authenticate"); the screen goes back to the splash; the system is headless. Blocks written since the last flush are lost, as with v3's unclean detach (my call).
- Plugging it back in finds the same partitions again; Artemis is reattached, Zuse is recognised and logged in, the console comes back.
- The kernel keeps running from memory while the stick is out: it was loaded into RAM at boot.
8. The splash
StarshipOS.png(1358×905; tracked at the repo root, copied tocapsules/v4/splash/) is converted when the image is built by a PNG-only converter in mkcapsule (ruled: the general "Tika-ish" converter interface queued 2026-10-16 is designed later): PNG in, scaled to 1024×683, the framebuffer's raw 32-bit pixel format out (about 2.7 MB), with its width and height, baked in as a capsule blob like the fonts. Its capsule ID is the hash of the converted pixels. The PNG is decoded on the build machine (zlib there); nothing PNG-shaped reaches the kernel.- On screen: the image centred on black, scaled down if the screen is smaller (never up), and a progress bar under it.
- The progress bar (my call) advances at fixed boot milestones the kernel already passes: hardware up, the ROM has assembled the system, the capsules are loaded, POST has passed, the disks are found, Zuse is recognised (or minted). Six steps; it does not estimate time.
- Serial carries the full boot log throughout, as today.
9. QEMU, and parity
Standing rule: "we must ALWAYS maintain QEMU and bare metal builds hold parity."
- QEMU boots the stick image itself, as
boards/BRINGUP.md§3.2 rehearses the PC image: q35 with OVMF, the image as a USB stick on the xHCI controller (a copy of it: the kernel writes to it), no-cdrom, no virtio disk, no separate thumbdrive. The kernel finds Artemis and Zuse through the same USB storage driver and GPT code it uses on a PC. - The
clean qemuboots, all three ISAs (ruled): each attaches a small GPT data stick — the identity and Artemis partitions, no ESP — over USB on the xHCI controller, in place of the virtio disk and the raw scratch identity drive. Built bymakefrom the same partition layout as the stick (§4), fresh for each boot, so the first boot mints. Every v4 boot then finds Zuse and Artemis the same way, on every ISA; virtio Artemis leaves the v4 path (sk_v4_block_chainkeeps fast RAM and the ramdrive). v3's own boot (system=v3) is not changed. - Entropy: QEMU's CPU is given RDRAND (
-cpu maxor+rdrand), so the same RDRAND path runs in both; virtio-rng is not what makes minting work in QEMU. - The screen and keyboard: QEMU's display and a USB keyboard on its xHCI controller, and its PS/2 keyboard, are the same drivers the PC uses.
- Acceptance once the stick works: the three-ISA
clean qemuboots with the data stick, to[zuse@Hera] ok>with POST passing anddict_hashequal; and for x86_64 the stick image booted as above, from a fresh copy (first boot: genesis) and then the same copy again (recognition). The identity gate's QEMU defaults (D4:disk/zuse-scratch/) are retired then. - What QEMU cannot show (written down, not assumed): the PC's own firmware and its USB
controller's firmware handoff (
BRINGUP.mdA1), its real framebuffer modes, a legacy-free PC's PIC (S3). Those wait for the bench.
10. Goals, non-goals, anti-goals
Goals: §2, on a real x86_64 PC and identically in QEMU; v4 only.
Non-goals (later designs): INSTALL; DOE, SDK, demos; WIREBIND identities and other
users on the stick; ARM and RISC-V sticks (the Pi build later adds a GPIO vocabulary/VM, which does
not exist yet); growing the image to fill a bigger stick.
Anti-goals — a failure even if it boots:
- Anything written to the PC's own disks before
INSTALL. - Two sticks sharing one Zuse (every stick mints its own).
- A prompt on screen with no Zuse logged in, or typed-ahead keys run as her (the identity gate's review items 1 and 4 stand).
- A path that works in QEMU and not on a PC, or the reverse.
- v3 code changing behaviour (shared code split out, as D1, with v3's behaviour unchanged).
11. What is built, in order
Each an increment with the full acceptance (.claude/CLAUDE.md), each test a QEMU session written
first and seen to fail:
- The keyboard bridge shared, and the v4 screen: the framebuffer and the USB/PS-2 keyboard on the v4 path (§5.3, §5.4); serial-only text until login; the console on screen after.
- The GPT reader and partition block devices, every ISA (§4); raw devices still read as now.
- The images: the stick (three partitions) and the data stick (two), Artemis formatted and
signed at build (§4); QEMU boots the stick as a USB stick, and every
clean qemuboot attaches the data stick (§9). - Artemis and Zuse from one disk: the boot device from the loader, the partitions found and
attached, virtio Artemis off the v4 path; recognition of a minted stick; entropy on the v4 path;
system=v3refused on a stick (§4, §5). - Genesis on the stick (§6).
- Pull and replug (§7), and the flush.
- The splash and progress bar (§8), with the mkcapsule PNG converter.
- Acceptance moves to the stick boot for x86_64 (§9).
12. Left to the builder
- The two StarshipOS partition type GUIDs (generated once, recorded in a header and in
mkdiskimage.sh). - How the GPT reader handles a damaged primary header (use the backup, or refuse; refusing is enough for a stick we wrote).
- The splash blob's exact header, and how the converter fits the "Tika-ish" interface's table.
- Where the shared keyboard bridge lives (a HAL input file, not
repl.c).