feat(kernel): entropy on the v4 path; QEMU's amd64 CPU has RDRAND, as a PC's

sk_v4_block_chain calls rng_init() after pci_init, with v3's two lines ("entropy: ready" / "entropy:
not available (continuing without)"); genesis on a fresh stick (increment 5) needs it. amd64 QEMU
runs -cpu qemu64,+rdrand (qemu, qemu-stick, qemu-esp) and the amd64 qemu target drops virtio-rng,
so QEMU takes the PC's RDRAND path; aarch64 and riscv64 keep virtio-rng, their only backend.

qemu_session.py: mode entropy (rdrand on amd64, both targets; virtio-rng on aarch64/riscv64; then
entropy: ready). system=v3 sessions get Zuse's raw identity image: v3 never reads a GPT, so the
Zuse stick (Task 1) left v3_keys headless -- found here; CLAUDE.md says so for v3 boots.

Tests: entropy FAIL x4 before, PASS x4 after; v3_keys PASS (rng: backend = rdrand). Acceptance:
amd64, aarch64, riscv64 to [zuse@Hera] ok>, POST 538/538, dict_hash 0xfec8c47cfc6f437f; v4 suite
and test-32 0 failures.

Plan: docs/v4.0.0/plans/2026-10-27-stick-4-one-disk.md, Task 2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-28 10:27:07 -04:00
co-authored by Claude Opus 5.5
parent f5866d39cc
commit 95f5afed5c
30 changed files with 19865 additions and 7 deletions
+22 -1
View File
@@ -49,6 +49,9 @@ the stick's, plan 2026-10-26-stick-1-screen-and-keyboard.md):
blank identity partition attached (500 MiB, not the 2 GiB disk); headless
datastick --make "DATASTICK=1 ...": the data stick over USB beside Zuse's drive; Zuse
still logs in; the data stick's identity partition attached
entropy after "System: StarForth v4", the entropy backend -- rdrand on amd64 (qemu and
--target qemu-stick), virtio-rng on aarch64 and riscv64 -- then "entropy: ready";
on the qemu target, [zuse@Hera] ok> (plan 2026-10-27-stick-4-one-disk.md, Task 2)
Needs only Python 3. One QEMU at a time (.claude/CLAUDE.md).
"""
@@ -88,8 +91,11 @@ subprocess.run(["bash", os.path.join(ROOT, "scripts/mkdiskimage.sh"), "--out", z
check=True, stdout=subprocess.DEVNULL)
attach_zuse = not (a.no_zuse or a.mode in NO_ZUSE_MODES)
# v3 reads identity drives raw, never through a GPT (only the v4 path reads one: sk_v4_identity.c),
# so a system=v3 boot gets Zuse's raw identity image, not her stick (plan 2026-10-27-stick-4, R2)
zdrive = ident if a.mode == "v3_keys" else zimg
make_args = ["make", "-f", "kernel/Makefile", f"ARCH={a.arch}", "clean", a.target, f"ARTDISK={art}",
f"ZUSEDISK={zimg if attach_zuse else ''}"] + shlex.split(a.make)
f"ZUSEDISK={zdrive if attach_zuse else ''}"] + shlex.split(a.make)
if a.mode == "v3_keys":
make_args.append("KERNEL_ARGS=system=v3")
start = time.time()
@@ -323,6 +329,21 @@ elif m in ("stick_boot", "datastick"):
check(f"the data stick's identity partition attached (user blocks {users})", found)
check("no fault", count(r"EXCEPTION|PANIC|panic") == 0)
elif m == "entropy":
want = "rdrand" if a.arch == "amd64" else "virtio-rng"
wait_for(r"entropy: (ready|not available)|Zuse:|ok> ", 120) # the block chain runs after POST
t = text()
v4 = re.search(r"System: StarForth v4", t)
after = t[v4.end():] if v4 else ""
check("System: StarForth v4", v4 is not None)
be = re.search(r"rng: backend = (\S+)", after)
check(f"after it, rng: backend = {want} (got {be.group(1) if be else None})",
be is not None and be.group(1) == want)
check("entropy: ready", re.search(r"entropy: ready", after) is not None)
if a.target == "qemu":
check("[zuse@Hera] ok>", wait_for(PROMPT, 120))
check("no fault", count(r"EXCEPTION|PANIC|panic") == 0)
elif m == "hotplug":
check("no ok> for 20 s with no drive", not wait_for(ANYPROMPT, 20))
add_zuse(1)