121 lines
6.0 KiB
Markdown
121 lines
6.0 KiB
Markdown
# 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.
|