docs(v4): the x86_64 StarshipOS stick, designed
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>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
34737f52a6
commit
1a54f9ef59
@@ -0,0 +1,242 @@
|
||||
# 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 `build` that can deliver
|
||||
> the entire OS for x86_ 64 asap." (Captain Bob, 2026-10-26)
|
||||
|
||||
> "we want a functional `try it` image 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
|
||||
|
||||
1. They boot the stick from the PC's firmware boot menu.
|
||||
2. 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.
|
||||
3. **First boot of a stick:** the kernel finds no Zuse on it and mints one — "minted on first
|
||||
boot, each stick its own Zuse."
|
||||
4. **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.
|
||||
5. 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.
|
||||
6. 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 thin `blkio` device 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_device` removes 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 (the `clean qemu` boots
|
||||
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 `STFR` volume header and its `artemis_sig_t` genesis 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
|
||||
whose `artemis_sig_t` checks out.)
|
||||
|
||||
## 5. Boot
|
||||
|
||||
Everything the identity gate does today (`kernel/src/v4/sk_v4_identity.c`), with five changes:
|
||||
|
||||
1. **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).
|
||||
2. **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 the `clean qemu`
|
||||
boots mint with virtio-rng, the only backend those ISAs have (`BRINGUP.md` A5): a known
|
||||
QEMU-only path, which their own sticks (later) must replace with real hardware entropy.
|
||||
3. **The screen.** The framebuffer is brought up on the v4 path, as v3 does (`console_fb_init`,
|
||||
`kernel_main.c` v3 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.
|
||||
4. **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 of `repl.c` into a file both paths use, unchanged in behaviour, and the v4 line
|
||||
editor reads it as well as serial.
|
||||
5. **`system=v3` is 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=v3` is 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_attach` as `capsule_zuse_boot_check` was (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_all` in
|
||||
`sk_repl_idle` is the same code as `SAVE-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 to `capsules/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 qemu` boots, 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 by `make` from 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_chain`
|
||||
keeps fast RAM and the ramdrive). v3's own boot (`system=v3`) is not changed.
|
||||
- **Entropy:** QEMU's CPU is given RDRAND (`-cpu max` or `+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 qemu` boots with the data stick, to
|
||||
`[zuse@Hera] ok>` with POST passing and `dict_hash` equal; 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.md` A1), 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:
|
||||
|
||||
1. **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.
|
||||
2. **The GPT reader** and partition block devices, every ISA (§4); raw devices still read as now.
|
||||
3. **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 qemu` boot attaches
|
||||
the data stick (§9).
|
||||
4. **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=v3` refused on a stick (§4, §5).
|
||||
5. **Genesis on the stick** (§6).
|
||||
6. **Pull and replug** (§7), and the flush.
|
||||
7. **The splash and progress bar** (§8), with the mkcapsule PNG converter.
|
||||
8. **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`).
|
||||
Reference in New Issue
Block a user