feat(build): QEMU boots the stick; the data stick over USB
qemu-stick boots the amd64 stick image (build/boards/pc/lithos-pc.img, copied per run) as a USB drive on q35, exactly as hardware would. DATASTICK=1 adds the data stick to any qemu run as a second USB drive. qemu_session.py gains --target and the stick_boot and datastick modes. Checks: stick_boot (the stick's own identity partition attaches, headless on a blank identity); datastick on amd64/aarch64/riscv64 (both drives found, the data stick's 500 MiB identity attaches); the seven GPT modes, the identity-gate and increment 1 sessions, emergency; the suite; three acceptance boots to [zuse@Hera] ok> with POST 538/538 and dict_hash=0xfec8c47cfc6f437f; test-32 0 failures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
e177c5c6b3
commit
c416c805cb
+33
-2
@@ -44,6 +44,10 @@ the stick's, plan 2026-10-26-stick-1-screen-and-keyboard.md):
|
||||
gpt_read_error the raw Zuse drive with reads of its sector 0 failing (blkdebug): not used,
|
||||
said so, not attached
|
||||
virtio_kbd aarch64/riscv64: QEMU's virtio keyboard types 7 ok
|
||||
stick_boot --target qemu-stick (amd64): the PC stick booted as a USB stick through OVMF; its
|
||||
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
|
||||
|
||||
Needs only Python 3. One QEMU at a time (.claude/CLAUDE.md).
|
||||
"""
|
||||
@@ -59,13 +63,14 @@ ap.add_argument("arch")
|
||||
ap.add_argument("--label", default=None)
|
||||
ap.add_argument("--make", default="")
|
||||
ap.add_argument("--no-zuse", action="store_true")
|
||||
ap.add_argument("--target", default="qemu") # qemu-stick: boot the PC stick (amd64)
|
||||
a = ap.parse_args()
|
||||
|
||||
NO_ZUSE_MODES = {"gpt_zuse", "gpt_hotplug", "gpt_foreign", "gpt_bad_crc", "gpt_bad_entries", "gpt_no_header",
|
||||
"gpt_read_error", "headless", "hotplug", "midpull", "waitpull", "typeahead", "emergency",
|
||||
"alttab_after_logout", "alttab_before_pull", "emergency_pull",
|
||||
"screen_dark_until_login", "screen_console_after_login", "screen_dark_after_logout",
|
||||
"kbd_typeahead"}
|
||||
"kbd_typeahead", "stick_boot"}
|
||||
label = a.label or f"{a.mode}-{a.arch}"
|
||||
work = os.path.join(ROOT, "build", "qemu-session", label)
|
||||
shutil.rmtree(work, ignore_errors=True)
|
||||
@@ -76,7 +81,7 @@ art = os.path.join(work, "artemis.img")
|
||||
zimg = os.path.join(work, "zuse-thumb-ident.img")
|
||||
attach_zuse = not (a.no_zuse or a.mode in NO_ZUSE_MODES)
|
||||
|
||||
make_args = ["make", "-f", "kernel/Makefile", f"ARCH={a.arch}", "clean", "qemu", f"ARTDISK={art}",
|
||||
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)
|
||||
if a.mode == "v3_keys":
|
||||
make_args.append("KERNEL_ARGS=system=v3")
|
||||
@@ -285,6 +290,32 @@ elif m == "zuse":
|
||||
type_line("3 4 + .")
|
||||
check("7 ok, and a prompt", wait_for(PROMPT, 60, n) and re.search(r"7\s+ok", text()) is not None)
|
||||
|
||||
elif m in ("stick_boot", "datastick"):
|
||||
# a 500 MiB identity partition: about 380000 user blocks (64 MiB gave 48724); the whole
|
||||
# 2 GiB stick would be over 1.5 million
|
||||
def ident_attached():
|
||||
# "use", not "user": the kernel cuts log messages at 63 characters (LOG_LINE_MAX 64,
|
||||
# v3/include/vm.h), and with a seven-digit LBN the attach line ends "(383542 use"
|
||||
users = [int(u) for u in re.findall(r"blk: disk .*?\((\d+) use", text())]
|
||||
return any(300000 < u < 512000 for u in users), users
|
||||
if m == "stick_boot":
|
||||
check("System: StarForth v4", re.search(r"System: StarForth v4", text()) is not None)
|
||||
time.sleep(20)
|
||||
found, users = ident_attached()
|
||||
check(f"the stick's identity partition attached, not the disk (user blocks {users})", found)
|
||||
check("no ok> for 30 s (a blank identity: headless)", not wait_for(ANYPROMPT, 30))
|
||||
else:
|
||||
check("Zuse: identity confirmed", wait_for(r"Zuse: identity confirmed from attached thumbdrive", 120))
|
||||
check("[zuse@Hera] ok>", wait_for(PROMPT, 60))
|
||||
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(f"two USB drives found ({count(r'blkio_usb: MSC device ready')})",
|
||||
count(r"blkio_usb: MSC device ready") >= 2)
|
||||
found, users = ident_attached()
|
||||
check(f"the data stick's identity partition attached (user blocks {users})", found)
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user