Run DOOM on an iPhone 7 (iPhone9,3, A10) outside SpringBoard:
checkm8 → SSH ramdisk (SSHRD) → framebuffer + SSH controls, with optional sound on the Mac over USB.
Not an App Store / jailbreak tweak app. You boot a tethered SSHRD every time.
| Piece | Status |
|---|---|
Display via IOMobileFramebuffer + IOSurface |
Works (fullscreen, landscape) |
Keyboard over SSH (wasd / fire / use) |
Works |
| Touch overlay (IOHID) | Experimental |
| Phone speakers (AudioQueue) | No mediaserverd in SSHRD |
| Sound on Mac speakers (TCP PCM) | Works |
Persistent install on sealed /mnt1 |
Often RO; use RAM disk /mnt2 when NAND is sealed |
- checkm8 device (iPhone 7)
- Mac with SSHRD_Script (or equivalent),
iproxy,expect - Windows optional — this repo; build happens on the Mac
- iPhoneOS SDK (Xcode or Theos SDK)
- IWAD: Freedoom or shareware
doom1.wad(not redistributed here)
doom_build/doomgeneric/doomgeneric/ # doomgeneric + iOS backends
doomgeneric_iosfb.c # framebuffer
doom_ios_touch.c # touch (experimental)
i_iossound.c # TCP PCM sound → Mac
Makefile.iphoneos
entitlements.plist
tools/
mac_pcm_player.c # Mac AudioQueue PCM server :23432
ichroot.c # tiny chroot helper
play_doom_pcm.py # optional sox/ffplay player
scripts/
patch_sshrd_skip_logo.py # comment out logo/setpicture in sshrd.sh
push_doom_files.exp # ramdisk + scp doom/wad
run_doom_tcp_sound.exp # SSH -R + launch
rebuild_pcm.sh / build_*.sh # Mac build helpers
Upstream engine: ozkl/doomgeneric (GPL).
export PATH=/usr/local/bin:/opt/homebrew/bin:$PATH
# USB SSH
iproxy 2222 22 &
# Mac sound player
clang -O2 -o /tmp/mac_pcm_player tools/mac_pcm_player.c -framework AudioToolbox
/tmp/mac_pcm_player &
# Build doom (once)
cd doom_build/doomgeneric/doomgeneric
make -f Makefile.iphoneos -j4 SDK=$HOME/sdks/iPhoneOS.sdk
codesign -s - --force --entitlements entitlements.plist ./doom
# Get IWAD → doom1.wad next to binary on Mac, then push + run:
expect scripts/push_doom_files.exp # creates /mnt2 ramdisk if needed
expect scripts/run_doom_tcp_sound.exp # reverse tunnel + gamePassword on device SSH: alpine (SSHRD default).
wasd— move / turnjorf— firespace— useEnter/Esc- Phone landscape, Home button to the right
-sndport 23433— phone connects to SSH-R 23433:127.0.0.1:23432-sndhost/-sndport— override- Mac must be running
mac_pcm_playeron127.0.0.1:23432
SSHRD is tight. Default zone is 6 MiB. If you OOM:
/mnt2/doom/doom -mb 6 -iwad /mnt2/doom/doom1.wad -sndport 23433
Avoid huge -mb (e.g. 16) — jetsam may SIGKILL.
- Boot: DFU →
gaster pwn→./sshrd.sh boot - Skip logo so the display isn’t held (see
scripts/patch_sshrd_skip_logo.py) - If
/mnt1is sealed/RO ordisk0s1s*missing, use a RAM disk on/mnt2(hdik ram://…+newfs_hfs) — scripts do this - RAM disk contents vanish on reboot — re-push after each boot
- doomgeneric / Chocolate Doom heritage: GPL
- DOOM data: only use IWADs you have rights to (Freedoom or purchased IWADs)
- checkm8 / SSHRD: research / your own device; tethered boot only
- Tethered: every cold boot needs USB + checkm8
- No reliable on-device speakers under SSHRD without
mediaserverd - Touch is best-effort; SSH keys are the reliable input
- ozkl/doomgeneric
- verygenericname/SSHRD_Script
- Freedoom project