proto E
Apply to Design Partner Program
// protoxe-cli reference

CLI Manual

protoxe-cli is the command-line front-end to protoXE: it boots real software on composed ARM64 and RISC-V machines, assembles boards from data, and runs the differential oracles that validate the emulator against QEMU and real silicon.

ARM64 EL0–EL3 RISC-V RV64 · Sv39 · SBI · PLIC #![no_std] Source of truth: docs/protoxe-cli.md

Quick start

Invoke either the built binary or, during development, via Cargo:

protoxe-cli <command> [args...] [flags...]

# development
cargo run -p protoxe-cli -- <command> [args...]

Running with no command executes the built-in demo battery (assembles a stock RK3588 BOM and self-tests UART, IRQ, MMU, etc.) — a quick smoke test that the build works.

Flags may appear anywhere on the line; positional arguments are matched in order after flags are filtered out. Addresses are hex (0x...); instruction counts accept K/M/G decimal suffixes where noted.

Common flags

Shared by the boot commands that support them.

--gdb[=<port>]

Expose a GDB remote stub and wait for an attach. Attach with gdb-multiarch -ex 'target remote :1234'. Supports breakpoints, single step, register/memory inspection (MMU-translated), and reverse debugging via monitor record on + bs.

  • --gdb → 127.0.0.1:1234
  • --gdb=<port> → 127.0.0.1:<port>
  • --gdb=:<port> → 0.0.0.0:<port> (all interfaces, e.g. attach from WSL)
  • --gdb=<host>:<port> → that endpoint
--api[=<port>|<host:port>]

Serve the JSON control API + web GUI while the guest runs. Default 127.0.0.1:9000. --api=:<port> binds all interfaces.

--audit

Record an instruction-coverage audit — which encodings the guest exercised, and which hit Unknown — for the ISA long-tail triage.

Environment variables

VariablePurpose
PROTOXE_QEMUPath to qemu-system-aarch64 for the difftest oracle.
PROTOXE_RK_DTB=<dtb>Boot an external device tree on bootrk3588 (drives the model with the real silicon's DTB; memory is clipped to model RAM).
PROTOXE_USB_KBD=1Enable the demo USB-HID keyboard auto-typer (bootrk3588).
PROTOXE_*_LOGPer-device host-side tracing (built with the std feature).
// chapter 1

Boot real software

bootlinux

Boot an unmodified arm64 Linux kernel to an interactive shell on a QEMU-virt-shaped board (RAM, GICv3, PL011, virtio-blk, RAZ/WI sinks for the rest).

protoxe-cli bootlinux <Image> <dtb> [initramfs] [disk.ext4] [--audit] [--gdb[=port]]
  • <Image> — the arm64 Image (kernel 6.6).
  • <dtb> — the device tree (e.g. a generated virt.dtb).
  • [initramfs] — optional initramfs (cpio).
  • [disk.ext4] — optional ext4 image mounted r/w as /dev/vda (virtio-blk).

Supports interactive input (host stdin → PL011 RX IRQ), SMP (N cores from the DTB via PSCI CPU_ON), and a real on-disk ext4 root.

protoxe-cli bootlinux Image virt.dtb initramfs.cpio rootfs.ext4

bootrk3588

Boot Linux on the composed, silicon-validated RK3588 board (the real R1 device map).

protoxe-cli bootrk3588 <Image> [initramfs] [flags...]
FlagEffect
--smpFull 4×Cortex-A76 + 4×Cortex-A55 (else a single core).
--disk <path>Back the virtio-mmio transport with an image (→ /dev/vda).
--demo-diskBuild a minimal ext2 root in-process and boot off it.
--demo-initUse a built-in demo init.
--fastRun the fast decode-cache backend (bit-exact, ~10% faster on a full boot).
--replay-checkSnapshot a boot mid-flight, replay a window, and assert the machine digest matches (deterministic-replay oracle).
--audit, --gdb, --apiSee common flags.
PROTOXE_RK_DTB=r1-rk3588s.dtb protoxe-cli bootrk3588 Image --smp

bootoptee

Boot the real OP-TEE OS (Trusted OS) at Secure-EL1; a Rust EL3 monitor drives a Non-secure client through the real OPTEE_SMC ABI.

protoxe-cli bootoptee <tee.bin> [--audit] [--gdb[=port]]

boot (alias bootel2)

Load a bare-metal ELF payload and start the primary core at a chosen exception level (--el <N>), honouring the ELF entry. EL2 emulates an EL3 firmware handoff to a Type-1 hypervisor, EL1 a kernel, EL3 secure firmware.

The diagnostic of choice for bare-metal bring-up at any level: symbolized fault reporting (<symbol+0x..>), a decoded ESR/FAR/register dump for the current EL, stop-on-fault at the root cause, and a stuck/cascade detector. A BRK the payload places on purpose (any immediate except #0x800, reserved for the kernel WARN/BUG path) is a first-class software breakpoint / checkpoint.

bootel2 is the --el 2 shorthand — protoxe-cli bootel2 … is exactly protoxe-cli boot --el 2 ….

protoxe-cli boot [--el N] [--board file] [--load file@addr]... \
                  [--run] [--steps N] [--fast] [--gdb[=port]] \
                  [--rewind N] [--mmio-trace[=N][@LO-HI]] \
                  [--exc-trace[=N][@FILTER]] [--break-on-bug] \
                  [--to N] [--save f] [--resume f] <payload.elf>

Core options

--el <N>Enter at exception level N (0/1/2/3). Default 2. The end-of-run state dump and fault report read the banked ESR/FAR/ELR/SPSR for whichever EL the core is in.
--board <file>Boot on an exact machine from a .board description (e.g. boards/r1-el2.board). Without it, a built-in RK3588-shaped board (512 MiB @ 0x40000000, GICv3, DW-8250 console, broad RAZ/WI sinks) is used.
--load <file>@<addr>Place a flat blob (a Linux Image / dtb / initramfs) at <addr> on the bus, QEMU -device loader,file=,addr= style. Repeatable.
--runAlias --no-stop-on-fault. Do not stop on the payload's own fault; let it handle every exception itself.
--steps <N>Alias --run-insns. Instruction budget; suffix K/M/G (--steps 10G), or 0 for unbounded. Default 200M.
--fastThe fast decode-cache backend (bit-exact, ~7× faster); shortens a boot-per-iteration loop.

See Diagnostic suite for --gdb, --rewind, --mmio-trace, --exc-trace, --break-on-bug.

protoxe-cli bootel2 --board boards/r1-el2.board \
  --load linux-guest/Image@0x40800000 \
  --load guest.dtb@0x46800000 \
  --load initramfs.cpio@0x47000000 \
  --steps 10G hypervisor_rk3588.elf

bootriscv

Run a RISC-V (RV64) payload on a virt-shaped board with a console UART. Experimental.

protoxe-cli bootriscv [program.elf | program.bin] \
                      [--steps N] [--fast] [--gdb[=port]] \
                      [--rewind N] [--mmio-trace[=N][@LO-HI]]

No argument runs a built-in hello demo that drives the console UART. An ebreak is a software breakpoint that stops the run.

bootriscv hands off to the same shared diagnostic runner as boot, so it inherits every diagnostic described below — symbolized fault reporting, the register dump (here RISC-V mcause/mtval/mepc/mstatus + x0x31), the stuck detector, recent activity, the MMIO access trace, snapshot rewind/trail, and the GDB stub.

// chapter 2 · the killer differentiator

Diagnostic suite

The flag set every boot/bootriscv run can opt into. Off by default, zero-overhead when off.

--rewind <N>

Time-travel

Keep a single rolling whole-machine snapshot, refreshed every N instructions. On any stop (fault / stuck / step-limit) the machine is restored to that point (≤N before) and, with --gdb, the stub is served there so you single-step forward into the fault; without --gdb, it prints an instruction trail into the stop (the last ~48 EL/PC).

Snapshot-backed replay is the sound form of reverse: a pure undo-log can't un-do device side effects — a UART tx, a GIC ack.

--mmio-trace[=<N>][@<lo>-<hi>]

Device-register ring

Capture the most recent N MMIO accesses (default 256) into a ring and print them on a stop: sequence number, direction, size, address annotated with the device it hit (<name+0xoff>), and the value written/read.

Bulk-memory (RAM) traffic is excluded — this is the register stream only. An optional inclusive address window @<lo>-<hi> restricts capture (e.g. --mmio-trace=512@0xFE600000-0xFE60FFFF keeps only GIC-distributor traffic). Accesses the device rejects are flagged !FAULT.

--exc-trace[=<N>][@<filter>]

Ordered exception stream

Capture the most recent N (default 64) exceptions/interrupts taken into a ring and print the ordered sequence on a stop: sequence number, target level, kind + decoded class (sync EC=0x.., or IRQ/FIQ with its INTID), the faulting/return address ELR (symbolized) and FAR.

Telemetry gives counts; this gives the order — the tool for an exception-nesting overflow. Optional @<filter> restricts capture to a target EL (EL0..EL3) or kind (irq/fiq/sync/serror).

--break-on-bug

Pre-panic catch

Stop the run at a kernel BRK #0x800 (the BUG/WARN entry, normally vectored to EL1) before its byte-by-byte panic-print floods the trace. Combine with --exc-trace/--rewind to catch the recursion that led to the panic instead of the post-panic park.

--save <f> · --resume <f> · --to <N>

Reproducers

Capture and share machine state at any icount. <command> --to <icount> replays to the exact point of a bug every time — the deterministic-reproducer story.

// always on, no flag

At the end of a run, boot prints exception/interrupt telemetry: synchronous exceptions by target EL and ESR class, plus IRQ/FIQ/SError counts per EL. A flat/missing line is itself a signal.

// chapter 3

Boards as data

protoXE topologies are .board text files — M2 declarative composition. See the examples under boards/ and the format in protoxe-cli/src/board_file.rs.

board

Assemble (validate + build) a machine from a .board description and report it.

protoxe-cli board <file.board>

protoxe-cli board boards/r1.board
# → assembled board from boards/r1.board: 8 cores, 24 devices

dtbimport

Generate a .board from a flattened device tree — best-effort: known nodes are mapped, unmodelled peripherals are emitted as commented sink suggestions.

protoxe-cli dtbimport <in.dtb|in.dts> [out.board]

protoxe-cli dtbimport r1-rk3588s.dtb boards/r1.board

A DTB is an OS-visibility artifact: it carries the device map but not bus latencies, clock trees, or SMMU internals. Great for boot + diagnostics, not cycle-level fidelity.

api

Serve the JSON-over-TCP control API (and web GUI) on a board loaded from a file, so a script or the GUI can drive/recompose the machine live.

protoxe-cli api <board-file> [host:port]

Default endpoint 127.0.0.1:9000.

// chapter 4

Run / inspect

run

Load and run a bare ELF on a minimal board (no boot protocol).

protoxe-cli run <file.elf>

(no command) — demo battery

Assembles the stock RK3588 BOM and runs a self-test battery (UART TX, IRQ delivery, MMU translation, …), printing PASS/FAIL — a quick smoke test that the build works.

protoxe-cli
// chapter 5 · n-version validation

Validation oracles

difftest

The differential tester: drives QEMU (qemu-system-aarch64) paused on its gdbstub, injects instruction streams, and compares architectural state against protoXE in lockstep after every instruction; delta-debugging (ddmin) shrinks any divergence. Needs QEMU (set PROTOXE_QEMU).

protoxe-cli difftest [cases] [insns/case] [seed-hex] [port] [mode]

Positional: cases (default 200), insns per case (16), seed (hex, 0xC0FFEE), gdb port (1234). The mode is a keyword anywhere on the line:

ModeWhat it validates
(none)integer data-processing, load/store (all addressing forms), branches
neon+ Advanced SIMD (three-same/diff/misc, shifts, reductions, TBL, LD1-4, crypto)
fpFP arithmetic (f32/f64), FSQRT/FRINT, FP↔int conversions, ARM NaN propagation
sysEL/exception machinery: CPACR FP trap, SVC — compares ESR/ELR/SPSR/EL
mmupage-table walk + data abort — translated loads and FAR/ESR
replayboot-oracle Phase 0: replay a fixed program's per-insn state + MMIO reads
irqboot-oracle Phase 1: GICv3 SGI bring-up, retire-count-pinned injection
timerboot-oracle Phase 2: CNTP physical-timer → PPI 30
bootboot-oracle Phase 3: unified mini-firmware (UART MMIO + IRQ + ERET resume)
el2EL2 exception machinery (virtualization=on)
el3Category-A secure world (secure=on): EL3 entry + SMC routing, OP-TEE SMC ABI
el3memjust the S3 Secure-only memory-isolation scenario
opteejust the S4 OP-TEE discovery + CALL_WITH_ARG scenarios
protoxe-cli difftest 500 32 0x1 1234 neon

cpuverify

Lock-step a CPU-under-test against the golden ARM64 reference model.

protoxe-cli cpuverify [insns]      # a stand-in DUT vs the golden model (default 1000 insns)
protoxe-cli cpuverify rtl          # an RtlCpu (Verilator-shaped DUT) bridge, golden vs buggy
protoxe-cli cpuverify rv           # a real RV32I core verified against the golden model

rvoracle

A sovereign differential oracle for the RV64IM engine. The signature evidence: 2,000,000 RV64IM instructions, zero divergences.

protoxe-cli rvoracle [cases] [seed]        # vs the in-house spec-direct reference
protoxe-cli rvoracle qemu [cases] [seed]   # vs a real qemu-system-riscv64 (gdbstub)

Authoritative source: docs/protoxe-cli.md in the protoXE repository. Full technical documentation is available to Design Partners under NDA.