Skip to content

Run r2 on the Game Boy Advance and boot Linux - #21

Open
bokuweb wants to merge 1 commit into
mainfrom
gba-port
Open

bokuweb wants to merge 1 commit into
mainfrom
gba-port

Conversation

@bokuweb

@bokuweb bokuweb commented Oct 4, 2026

Copy link
Copy Markdown
Owner

Summary

Adds a gba/ frontend that runs the r2 RISC-V core on a Game Boy Advance and boots the bundled Linux (fixtures/linux.bin + default.dtb) to a shell.

Linux shell on the GBA

  • RAM: the GBA only has 288KB, so the upper 16MB of the 32MB GamePak window is used as guest RAM. This needs a flash cart that runs games out of PSRAM (or rgba with RGBA_PSRAM=1, Add flash-cart PSRAM emulation and a headless mode rgba#100). The kernel and DTB are embedded in the ROM and copied there at boot; the DTB memory size is patched the same way mini-rv32ima does.
  • Speed: the interpreter loop lives in IWRAM and is built as ARM code (armv4t-none-eabi, ~2.2x faster than Thumb): ~70 ARM instructions per RISC-V instruction, ~110K guest IPS. The login prompt appears after ~6–7 minutes of GBA time.
  • Clock: guest time comes from the instruction count (16 instructions/µs). At 1 instruction/µs the timer work starved userspace and the boot never reached the login prompt. WFI fast-forwards to the next timer interrupt.
  • Console: 60x26 text on the Mode 3 bitmap (X11 misc-fixed 4x6 font, public domain), mirrored to the mGBA debug log. Login is answered automatically, uname -a runs at the first prompt, and each button types a command (A: uname -a, B: ls /, ...).

Core changes

  • core and device_interfaces are now no_std; the Vec-backed Bus and start stay behind a default std feature, so app/wasm/wasi are unchanged.
  • LR/SC reservation is a single Option<(addr, value)> (consumed by SC) instead of a HashMap.
  • Cpu::bus_mut().

Notes

  • Only tested on rgba. Real hardware also needs a PSRAM-capable flash cart and a fixed header (gbafix); the logo/checksum are not filled in.
  • gba/ is its own workspace (nightly + build-std), so the root cargo check/CI does not build it.

Test plan

  • cargo check, cargo test -p core
  • make -C gba builds target/r2-gba.gba
  • On rgba (RGBA_PSRAM=1): boots, logs in, uname -a → Linux buildroot 6.1.14 ... riscv32 GNU/Linux

🤖 Generated with Claude Code

Add a `gba/` frontend that runs the RISC-V core on a GBA. Guest RAM is
the upper 16MB of the GamePak window, which flash carts with PSRAM expose
as writable memory; the kernel image and DTB are embedded in the ROM and
copied there at boot. The interpreter loop runs from IWRAM as ARM code,
the guest clock is derived from the instruction count, and the serial
console is drawn on the Mode 3 bitmap with buttons typing commands.

To make this possible the core and device_interfaces crates are now
no_std; the Vec-backed Bus and the `start` loop stay behind a default
`std` feature, so the existing frontends are unchanged. The LR/SC
reservation is a single Option instead of a HashMap, and Cpu gains
bus_mut().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant