Document VPX emulator status and recovery plan
This commit is contained in:
120
process-level-emulation.md
Normal file
120
process-level-emulation.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# Process-Level Game Emulation
|
||||
|
||||
## Scope
|
||||
|
||||
The process lane runs only the extracted AArch64 game/display target, game
|
||||
assets, extracted loader/library runtime, generated Mesa overlay, and clean-room
|
||||
machine model. It does not boot Buildroot and does not modify extracted evidence.
|
||||
|
||||
Implementation entry points:
|
||||
|
||||
- `spike3-emu`
|
||||
- `emulation/process/spike3_emu.py`
|
||||
- `emulation/process/config.default.json`
|
||||
- `emulation/process/Dockerfile`
|
||||
|
||||
Generated state is confined to `emulation/work/capsule/`,
|
||||
`emulation/work/runs/`, and `emulation/work/packs/`; all three are excluded from
|
||||
Git.
|
||||
|
||||
## Confirmed Static Runtime Contract
|
||||
|
||||
The launcher's dependency resolver was run against:
|
||||
|
||||
- `/games/pokemon_pro/game`
|
||||
- `/games/pokemon_pro/spike3/spike_menu/game`
|
||||
- `/games/pokemon_pro/spike3/bin/boot_display`
|
||||
|
||||
It resolves 51 unique `DT_NEEDED` libraries with no unresolved SONAMEs. The
|
||||
highest required and provided version nodes both match: `GLIBC_2.39` and
|
||||
`GLIBCXX_3.4.32`. This confirms that the extracted loader, glibc, and libstdc++
|
||||
must remain the process runtime; substituting Debian bookworm's older
|
||||
libstdc++ would be incompatible.
|
||||
|
||||
The initial asset capsule retains the full read-only
|
||||
`/games/pokemon_pro` directory. `trace` inventories actual file opens, and
|
||||
`pack --profile traced` creates a generated minimal tree whose copied files are
|
||||
verified against the read-only source with SHA-256.
|
||||
|
||||
## Runtime Architecture
|
||||
|
||||
| Layer | Implementation |
|
||||
| --- | --- |
|
||||
| Host selection | Apple Silicon uses an ARM64 Linux container; AArch64 Linux uses native execution; x86-64 Linux uses qemu-user. |
|
||||
| Isolation | Bubblewrap mounts game and target libraries read-only, creates an offline target network namespace, and binds only generated writable state. |
|
||||
| Machine I/O | `libspike3machine_client.so` connects `/dev/spidev4.0`, `/dev/i2c-10`, GPIO, and netbridge calls to `emulation/work/machine.sock`. |
|
||||
| Display | `libspike3emu_stub.so` writes XRGB frames to a generated regular `/dev/fb0`; ffplay loops the frame into Xvfb, then x11vnc/noVNC serves port 6081. |
|
||||
| Controls | Dashboard port 8090 uses the private Unix RPC socket; loopback-only TCP port 8091 serves VPX and other external controllers. |
|
||||
| Audio | ALSA is converted to fixed 48 kHz stereo S16LE file output and finalized as `audio.wav` per run. |
|
||||
| Debugging | Native uses extracted `gdbserver`; qemu-user uses `-g`; generated helpers resolve the PIE slide and named Ghidra offsets. |
|
||||
| System fallback | `--engine system` delegates to the existing `qemu-system-aarch64`/virtio-gpu/noVNC workbench. |
|
||||
|
||||
Generated safe command replacements log and block `reboot`, `halt`, `poweroff`,
|
||||
`shutdown`, and hostname changes. OpenOCD is replaced by a controlled stub whose
|
||||
exit status defaults to success. The machine service implements no physical
|
||||
outputs; the launcher's `hardware` backend is deliberately refused.
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
./spike3-emu prepare
|
||||
./spike3-emu run boot-display
|
||||
./spike3-emu run spike-menu
|
||||
./spike3-emu run game
|
||||
./spike3-emu debug game
|
||||
./spike3-emu trace game
|
||||
./spike3-emu pack --profile traced
|
||||
./spike3-emu clean --legacy-system
|
||||
./spike3-emu clean --legacy-system --yes
|
||||
```
|
||||
|
||||
Run artifacts include effective configuration, stdout, syscall trace, broker
|
||||
transactions, display-service logs, asset hashes, blocked commands, PCM/WAV
|
||||
capture, GDB setup, and exit status.
|
||||
|
||||
## Verified Runtime Results (2026-07-11)
|
||||
|
||||
`./spike3-emu prepare` completed on Apple Silicon with 51 resolved libraries.
|
||||
A repeat preparation completed from the dependency/config fingerprint cache in
|
||||
0.56 seconds. Docker inspection reported the image as `linux/arm64`, 340,201,729
|
||||
content bytes (1.36 GB virtual size). No QEMU process is used in process mode.
|
||||
|
||||
The ARM64 Mesa smoke command completed with framebuffer status `0x8cd5`, pixel
|
||||
`64,128,191,255`, EGL 1.4, and no GL error. Live `boot-display`, `spike-menu`,
|
||||
and `game` runs loaded the HLE preload and executed the target. The menu/game
|
||||
accepted netbridge CRC `0x357f5327`. Dashboard port 8090 returned broker state,
|
||||
and a direct JSONL request to `127.0.0.1:8091` returned a revisioned
|
||||
`state.delta`. Manual Start/launch/drain events changed the virtual lifecycle.
|
||||
|
||||
A one-shot `docker stats --no-stream` sample shortly after game startup was
|
||||
129.78% CPU, 200.9 MiB resident usage, and 63 container processes. The native
|
||||
game reached its netbridge CRC check in about 5.1 seconds in that run. This is a
|
||||
startup sample, not a five-minute steady-state benchmark. `docker top` showed
|
||||
the extracted `ld-linux-aarch64.so.1` launching `/games/game` under bubblewrap
|
||||
and no `qemu-system-*` or `qemu-aarch64` process. The legacy cleaner dry-run
|
||||
reported 6,505,625,192 removable bytes (6 GiB rootfs plus a 63,173,402-byte
|
||||
macOS runtime cache); those files were deliberately not removed automatically.
|
||||
Changing-game FPS is not measurable until the connector failure is resolved.
|
||||
|
||||
The remaining display limit is confirmed: software EGL and the synthetic DRM
|
||||
resource inventory initialize, but the proprietary window helper reports
|
||||
`failed to get DRM connector for display_number 1`; GBM buffers are therefore
|
||||
not allocated. Current nonzero framebuffer captures are HLE diagnostic frames,
|
||||
not genuine changing game frames. Short runs produced no WAV data. Five-minute
|
||||
attract mode, a target-observed full three-ball game, live GDB attachment, and
|
||||
VPX round-trip remain open.
|
||||
|
||||
Unit verification is 14 launcher tests, 25 machine-model tests, and 3 dashboard
|
||||
tests. Two machine socket-bind tests skip only because the managed test sandbox
|
||||
denies AF_UNIX/AF_INET binds; the live Docker TCP and Unix paths were exercised.
|
||||
|
||||
## VPX Bridge
|
||||
|
||||
`emulation/vpx-plugin/` is pinned to VPX commit
|
||||
`215129065954d265100e4fa7ff063154c6fedf5d`. Its build produced a Mach-O ARM64
|
||||
ControllerPlugin dylib with `Spike3ControllerPluginLoad` and
|
||||
`Spike3ControllerPluginUnload` exports. It forwards standard cabinet actions,
|
||||
publishes SPIKE binary inputs/controlled devices, reconnects safely, and exposes
|
||||
the `Spike3.Controller` script API. `example-spike3.vbs` covers target, lane,
|
||||
trough, and drain events. VPX is not installed in `/Applications` on this host,
|
||||
so actual VPX loading and bidirectional table verification are not claimed.
|
||||
Reference in New Issue
Block a user