diff --git a/docs/v4.0.0/plans/2026-10-29-stick-5-proxy-zuse-and-real-zuse.md b/docs/v4.0.0/plans/2026-10-29-stick-5-proxy-zuse-and-real-zuse.md index c44ba133..5e112326 100644 --- a/docs/v4.0.0/plans/2026-10-29-stick-5-proxy-zuse-and-real-zuse.md +++ b/docs/v4.0.0/plans/2026-10-29-stick-5-proxy-zuse-and-real-zuse.md @@ -343,3 +343,24 @@ on port 2 and no other drive: a first boot every time, the proxy minted, the pro - [ ] **Step 6:** A new PC stick (`make boot_image TARGET=PC`, no `STICK_PAIR`) for the SER5, and the bench steps written in `boards/BRINGUP.md`: plug in, boot, the prompt; `MINT-ZUSE` onto the second stick; boot with the system stick alone (the fixed screen); with both (the prompt). + +--- + +## Progress (kept current, one line per increment -- where to pick up) + +Tasks 1-3 accepted and merged (#159, master 594d2f93); #155 merged with them. + +**Task 4, `MINT-ZUSE`** (Captain Bob, 2026-11-08: "work in small increments and memorize frequently"): +- [x] 4.1 the first failing test: `qemu_session.py` mode `mint_zuse` and `add_stick(n, img, port)` +- [ ] 4.2 run `mint_zuse` on amd64 before any kernel change: FAIL expected (`MINT-ZUSE` unknown) +- [ ] 4.3 `gpt_write_one()` in `kernel/src/gpt.c` (one partition, protective MBR, both headers) +- [ ] 4.4 `sk_v4_identity_offer_wait()` / `sk_v4_identity_recheck_offered()`: a stick offered, not attached, while a mint waits +- [ ] 4.5 `sk_v4_mint.c`: the flow -- plug-in line, size line, `YES`, GPT, zeroed, minted, read back, marker +- [ ] 4.6 `MINT-ZUSE` in `sk_v4_words[]` (request 2): word_count 317 -> 318 +- [ ] 4.7 the real Zuse stick recognised and attached after the system stick; her session +- [ ] 4.8 `mint_zuse` passes on amd64; then the other tests: `mint_zuse_refuse`, `mint_pull_system`, `zuse_stick_first`, `mint_small`, the pair's stick offered +- [ ] 4.9 regressions, full acceptance on three ISAs (new dict_hash, equal), FABRIC entry, commit + +Working notes: the boot's own words are `sk_v4_words[]` in `kernel/src/v4/sk_v4.c`, served by +`sk_v4_serve(node, request)` with request = index + 1 (`BYE` is 1). Sticks are added in the harness +on port 3 (port 1: the minted pair's stick when a test names it; port 2: the data stick). diff --git a/scripts/qemu_session.py b/scripts/qemu_session.py index bf7b96ee..cbb2f256 100755 --- a/scripts/qemu_session.py +++ b/scripts/qemu_session.py @@ -63,6 +63,10 @@ the stick's, plan 2026-10-26-stick-1-screen-and-keyboard.md): on the copy is clean (plan 2026-10-29-stick-5, Task 2) stick_small --target qemu-stick --stick-gib 4: under 8 GB -- not grown, said so; Artemis at the image's size; the prompt + mint_zuse the default fresh data stick, the prompt; MINT-ZUSE; a blank 600 MiB stick added on port 3: + its size said, YES typed, "real Zuse minted onto the second stick", the prompt, 7 ok; + afterwards sfdisk --verify on it clean, one StarshipOS identity partition (plan + 2026-10-29-stick-5, Task 4) bam_flush --target qemu-stick --stick-gib 16: an Artemis block changed and SAVE-BUFFERS'd three times, each timed (TIME:); each answers ok within 2 s (#155: it took 5-6 s); then the BAM's bytes on the stick hashed (BAM:), to be the same before and after #155's change @@ -384,6 +388,12 @@ def add_zuse(n, img=None, fail_sector0=False): drive=f"zuse{n}", id=f"zusedev{n}") +def add_stick(n, img, port): + """A USB stick added over QMP on the xHCI controller's `port` (plan 2026-10-29-stick-5, Task 4).""" + qcmd("blockdev-add", driver="raw", **{"node-name": f"stick{n}"}, file={"driver": "file", "filename": img}) + qcmd("device_add", driver="usb-storage", bus="xhci0.0", port=str(port), drive=f"stick{n}", id=f"stickdev{n}") + + def del_zuse(n): qcmd("device_del", id=f"zusedev{n}") time.sleep(3) @@ -534,6 +544,37 @@ elif m in ("stick_grow", "stick_small"): v.returncode == 0 and "No errors detected" in v.stdout + v.stderr) boot_done = True +elif m == "mint_zuse": + blank = os.path.join(work, "zuse-real.img") + subprocess.run(["truncate", "-s", "600M", blank], check=True) + check("[zuse@Hera] ok> (the proxy, on a fresh data stick)", wait_for(PROMPT, 300)) + type_line("MINT-ZUSE") + check("MINT-ZUSE: plug in the stick for the real Zuse", + wait_for(r"MINT-ZUSE: plug in the stick for the real Zuse", 60), near=r"MINT-ZUSE") + add_stick(1, blank, 3) + check("MINT-ZUSE: a stick of 600 MiB -- all of it is erased", + wait_for(r"MINT-ZUSE: a stick of 600 MiB -- all of it is erased", 120), near=r"MINT-ZUSE") + check("MINT-ZUSE: type YES to write it", wait_for(r"MINT-ZUSE: type YES to write it", 30), near=r"MINT-ZUSE") + n = count(PROMPT) + type_line("YES") + check("Zuse: real Zuse minted onto the second stick", + wait_for(r"Zuse: real Zuse minted onto the second stick", 300), near=r"MINT-ZUSE|Zuse:") + check("[zuse@Hera] ok> (the real Zuse)", wait_for(PROMPT, 120, n)) + n = count(PROMPT) + type_line("3 4 + .") + check("7 ok", wait_for(PROMPT, 60, n) and re.search(r"7\s+ok", text()[-400:]) is not None) + check("no fault", count(r"EXCEPTION|PANIC|panic") == 0) + shutdown() + boot_done = True + sf = shutil.which("sfdisk") or "/usr/sbin/sfdisk" + v = subprocess.run([sf, "--verify", blank], capture_output=True, text=True) + print(v.stdout.strip() + v.stderr.strip(), flush=True) + check("sfdisk --verify on the new Zuse stick: clean", v.returncode == 0 and "No errors detected" in v.stdout + v.stderr) + j = subprocess.run([sf, "--json", blank], capture_output=True, text=True) + parts = json.loads(j.stdout)["partitiontable"]["partitions"] if j.returncode == 0 and j.stdout else [] + check(f"one StarshipOS identity partition ({[q['type'] for q in parts]})", + len(parts) == 1 and parts[0]["type"].upper() == GPT_IDENTITY) + elif m == "bam_flush": check("[zuse@Hera] ok>", wait_for(PROMPT, 600)) lbns = re.findall(r"blk: disk .*? LBN (\d+)\.\.(\d+)", text())