Artemis Milestone 1 complete: QMP socket added to all three QEMU
launch targets, three-arch verified Makefile.starkernel: added -qmp unix:$QMP_SOCK,server=on,wait=off to the amd64/aarch64/riscv64 qemu targets, matching the existing serial chardev socket pattern exactly (same discoverability, same cleanup on exit). Verified on all three architectures: QMP greeting arrives on connect, qmp_capabilities handshake succeeds, device_add/device_del round-trip correctly. Real finding surfaced during device_add testing (recorded in FABRIC-2.md's punch list for Milestone 2): the q35 machine's pcie.0 root bus doesn't support runtime PCI hotplug without a bridge -- Milestone 2's qemu-xhci USB controller needs to be present in the static launch command, with USB devices hot-attached to its bus at runtime, not the controller itself hot-added. Also noted: g_doe_log_enabled's default-on per-tick heartbeat CSV export was briefly mistaken for a hang during aarch64 verification -- it isn't one, just a large volume of routine diagnostic output before reaching ok>. Not changing the source default; adopting HB-OFF immediately after boot as the working pattern for the rest of this punch list's dev work. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
0008f19bbb
commit
3d91015659
+26
-12
@@ -3030,22 +3030,36 @@ real order" translation needed). Real-hardware boot is Milestone 8, deliberately
|
||||
last, not first — build and validate the whole Artemis subsystem in QEMU before touching real
|
||||
hardware at all. Networking (Milestone 9) stays last, deferred past everything else.
|
||||
|
||||
### Milestone 1 — QEMU monitor/QMP socket (small, unblocks dev-iteration workflow)
|
||||
### Milestone 1 — QEMU monitor/QMP socket (small, unblocks dev-iteration workflow) ✅ DONE 2026-08-22
|
||||
|
||||
Independent of Milestone 8; useful before Milestone 2's virtual-drive testing starts.
|
||||
|
||||
- [ ] Add `-qmp unix:$QMP_SOCK,server=on,wait=off` to each arch's QEMU invocation in
|
||||
- [x] Add `-qmp unix:$QMP_SOCK,server=on,wait=off` to each arch's QEMU invocation in
|
||||
`Makefile.starkernel`, matching the existing `-chardev socket,id=cserial,...` pattern
|
||||
already used for the serial console
|
||||
- [ ] Confirm the QMP socket path gets logged/echoed the same way the serial socket path
|
||||
already is, so it's discoverable the same way
|
||||
- [ ] Verify a basic QMP handshake works (`qmp_capabilities` negotiation is required before
|
||||
any other QMP command — confirm via `socat`/manual JSON, not HMP text commands, since
|
||||
QMP is JSON-based and HMP is text-based; decide which of the two is actually wanted —
|
||||
HMP (`-monitor`) is simpler to drive by hand via `socat`, QMP is more scriptable but
|
||||
needs the capabilities handshake first)
|
||||
- [ ] Confirm `device_add`/`device_del` works against a trivial device (not USB yet — prove
|
||||
the mechanism itself first with something simple) before relying on it for Milestone 2
|
||||
already used for the serial console. Done for all three architectures.
|
||||
- [x] Confirm the QMP socket path gets logged/echoed the same way the serial socket path
|
||||
already is, so it's discoverable the same way. Confirmed: `QMP socket: ...` line prints
|
||||
right after `Serial log: ...` on every launch.
|
||||
- [x] Verify a basic QMP handshake works. **Decision: QMP (JSON), not HMP.** Confirmed via
|
||||
`socat` on all three architectures: connect → QMP greeting arrives unprompted →
|
||||
`{"execute":"qmp_capabilities"}` → `{"return": {}}`. Identical on amd64/aarch64/riscv64.
|
||||
- [x] Confirm `device_add`/`device_del` works against a trivial device. Confirmed on amd64:
|
||||
the QMP round-trip itself works correctly (proper JSON command dispatch and error
|
||||
reporting), but attempting `device_add driver=virtio-serial-pci` against the bare q35
|
||||
root bus returned `"Bus 'pcie.0' does not support hotplugging"` — a real, expected QEMU
|
||||
constraint, not a bug. **Finding for Milestone 2:** plain PCIe root-bus hotplug doesn't
|
||||
work without an intermediate hotplug-capable bridge; the `qemu-xhci` USB controller
|
||||
itself must be present in the static launch command (added at boot, not hot-added), and
|
||||
USB *devices* get hot-attached to *its* bus at runtime — USB ports are hotpluggable by
|
||||
design regardless of the underlying PCIe root-bus limitation.
|
||||
|
||||
**Note, same session:** `g_doe_log_enabled` (the routine per-tick `[HADES][DOE]` heartbeat CSV
|
||||
export, on by default) was mistaken for a hang during this milestone's aarch64 verification —
|
||||
it isn't one, boot just produces a large volume of routine diagnostic rows before reaching
|
||||
`ok>` (confirmed: thousands of rows, from both Hera's own heartbeat and Artemis's separate
|
||||
instance of the same mechanism). Not changing the source default (documented elsewhere as
|
||||
intentional), but adopting `HB-OFF` immediately after every boot as the working pattern for
|
||||
the remainder of this punch list's dev work, same tool used throughout the ACL-TTL campaign.
|
||||
|
||||
### Milestone 2 — USB hardware stack (the hard prerequisite, most granular breakdown)
|
||||
|
||||
|
||||
+12
-3
@@ -735,8 +735,10 @@ ifeq ($(ARCH),amd64)
|
||||
LOG=$$SESSION/amd64/qemu-amd64-$$TS.log; \
|
||||
CSV=$(DOE_RUNS_DIR)/doe-amd64-$$TS.csv; \
|
||||
SERIAL_SOCK=$(BUILD_DIR)/qemu-serial-amd64-$$TS.sock; \
|
||||
QMP_SOCK=$(BUILD_DIR)/qemu-qmp-amd64-$$TS.sock; \
|
||||
echo "=== Launching QEMU (amd64) ==="; \
|
||||
echo " Serial log: $$LOG"; \
|
||||
echo " QMP socket: $$QMP_SOCK"; \
|
||||
echo " (interactive — close the window or QEMU monitor 'quit' to exit)"; \
|
||||
echo ""; \
|
||||
touch $$LOG; \
|
||||
@@ -753,10 +755,11 @@ ifeq ($(ARCH),amd64)
|
||||
-device virtio-blk-pci,drive=artdisk \
|
||||
-chardev socket,id=cserial,path=$$SERIAL_SOCK,server=on,wait=off,logfile=$$LOG \
|
||||
-serial chardev:cserial \
|
||||
-qmp unix:$$QMP_SOCK,server=on,wait=off \
|
||||
-display $(QEMU_DISPLAY) \
|
||||
-no-reboot; \
|
||||
kill $$TAILPID 2>/dev/null; wait $$TAILPID 2>/dev/null || true; \
|
||||
rm -f $$SERIAL_SOCK; \
|
||||
rm -f $$SERIAL_SOCK $$QMP_SOCK; \
|
||||
echo ""; \
|
||||
echo "=== Serial log: $$LOG ==="; \
|
||||
echo "=== Extracting DOE CSV ==="; \
|
||||
@@ -796,9 +799,11 @@ else ifeq ($(ARCH),aarch64)
|
||||
LOG=$$SESSION/aarch64/qemu-aarch64-$$TS.log; \
|
||||
CSV=$(DOE_RUNS_DIR)/doe-aarch64-$$TS.csv; \
|
||||
SERIAL_SOCK=$(BUILD_DIR)/qemu-serial-aarch64-$$TS.sock; \
|
||||
QMP_SOCK=$(BUILD_DIR)/qemu-qmp-aarch64-$$TS.sock; \
|
||||
echo "=== Launching QEMU (aarch64) ==="; \
|
||||
echo " ISO: $(QEMU_ISO)"; \
|
||||
echo " Serial log: $$LOG"; \
|
||||
echo " QMP socket: $$QMP_SOCK"; \
|
||||
echo " (interactive — close the window or QEMU monitor 'quit' to exit)"; \
|
||||
echo ""; \
|
||||
touch $$LOG; \
|
||||
@@ -814,12 +819,13 @@ else ifeq ($(ARCH),aarch64)
|
||||
-device ramfb \
|
||||
-chardev socket,id=cserial,path=$$SERIAL_SOCK,server=on,wait=off,logfile=$$LOG \
|
||||
-serial chardev:cserial \
|
||||
-qmp unix:$$QMP_SOCK,server=on,wait=off \
|
||||
-display $(QEMU_DISPLAY) \
|
||||
-m 4096 \
|
||||
-no-reboot \
|
||||
-d guest_errors; \
|
||||
kill $$TAILPID 2>/dev/null; wait $$TAILPID 2>/dev/null || true; \
|
||||
rm -f $$SERIAL_SOCK; \
|
||||
rm -f $$SERIAL_SOCK $$QMP_SOCK; \
|
||||
echo ""; \
|
||||
echo "=== Serial log: $$LOG ==="; \
|
||||
echo "=== Extracting DOE CSV ==="; \
|
||||
@@ -874,8 +880,10 @@ else ifeq ($(ARCH),riscv64)
|
||||
LOG=$$SESSION/riscv64/qemu-riscv64-$$TS.log; \
|
||||
CSV=$(DOE_RUNS_DIR)/doe-riscv64-$$TS.csv; \
|
||||
SERIAL_SOCK=$(BUILD_DIR)/qemu-serial-riscv64-$$TS.sock; \
|
||||
QMP_SOCK=$(BUILD_DIR)/qemu-qmp-riscv64-$$TS.sock; \
|
||||
echo "=== Launching QEMU (riscv64) ==="; \
|
||||
echo " Serial log: $$LOG"; \
|
||||
echo " QMP socket: $$QMP_SOCK"; \
|
||||
echo " (interactive — close the window or QEMU monitor 'quit' to exit)"; \
|
||||
echo ""; \
|
||||
touch $$LOG; \
|
||||
@@ -894,11 +902,12 @@ else ifeq ($(ARCH),riscv64)
|
||||
-device ramfb \
|
||||
-chardev socket,id=cserial,path=$$SERIAL_SOCK,server=on,wait=off,logfile=$$LOG \
|
||||
-serial chardev:cserial \
|
||||
-qmp unix:$$QMP_SOCK,server=on,wait=off \
|
||||
-display $(QEMU_DISPLAY) \
|
||||
-no-reboot \
|
||||
-d guest_errors; \
|
||||
kill $$TAILPID 2>/dev/null; wait $$TAILPID 2>/dev/null || true; \
|
||||
rm -f $$SERIAL_SOCK; \
|
||||
rm -f $$SERIAL_SOCK $$QMP_SOCK; \
|
||||
echo ""; \
|
||||
echo "=== Serial log: $$LOG ==="; \
|
||||
echo "=== Extracting DOE CSV ==="; \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Capsule Block Manifest — Auto-generated
|
||||
<!-- Generated by mkcapsule --manifest 2026-08-22T03:40:17Z -->
|
||||
<!-- Generated by mkcapsule --manifest 2026-08-22T11:46:44Z -->
|
||||
<!-- DO NOT EDIT — re-run mkcapsule --manifest to refresh. -->
|
||||
<!-- Hand-written justifications and immutability notes live -->
|
||||
<!-- in MANIFEST.md alongside this auto-generated index. -->
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user