Releases: samhenrigold/qemu-ios
Release list
iPod touch 2G — iOS 3.1.3
An iPod touch 2G (S5L8720) running iOS 3.1.3 (7E18). It boots to a usable home
screen, runs decrypted apps and real OpenGL ES games, plays sound (kinda), reaches the
network, and takes a debugger.
Just want to use it?
Download iPod-touch-2G-macOS.zip (249 MB). It is a notarized macOS app
with the emulator and the device inside it — no terminal, no Homebrew, nothing
to build. Unzip, drag to Applications, open.
Everything is in the Device menu: Home, Lock, volume, rotation, shake,
Install App…, Open Terminal (SSH), and Erase All Content and Settings.
It needs macOS 12 or later.
Six things worth knowing before you start:
- Launch it twice the first time. The first launch unpacks the device and
then stops. Open it again and you get the emulator. Every launch after that
is a single one. - A frozen, unresponsive screen is usually just sleep. Sometimes it boots up and immediately sleeps.
Press Cmd+L and see if it wakes up before assuming it has hung. - Join the WiFi yourself, in Settings ▸ Wi-Fi. The network is there; the
device does not auto-join it. - Find apps to install on Legacy Store (shameless self promo).
Apps must be decrypted and should support iOS 3.1.3 or lower.- If, on the first run, apps show their splash screen and then crash, you may need to restart the emulator. This is a one-time thing.
- The on-screen keyboard mishandles Shift and the symbol keys. Letters and
numbers are fine. - Some apps glitch in their launch and close animations. Known, cosmetic,
and being worked on.
Building it yourself
Download the images below and verify against SHA256SUMS.
Setup guide →
| Asset | What it is |
|---|---|
bootrom_240_4 |
S5L8720 bootrom, unchanged from upstream |
nor_7E18.bin |
3.1.3 NOR, SHSH wrapped for the emulated device |
nand-canonical.tar.gz |
Clean 3.1.3 image |
nand-appsync3.tar.gz |
Same, plus the patches that let decrypted apps launch |
nand-appsync3 boots with its code-signing gates open — that is what lets
decrypted apps launch and lldb attach, and it means it is not a faithful
device. Neither NAND image is a dump; both are built from
iPod2,1_3.1.3_7E18_Restore.ipsw, and imgtools/build_nand.py reproduces them
from an IPSW you supply.
Works
- Boots to an interactive home screen, and reboots
- Touch, multitouch (pinch-to-zoom), the on-screen keyboard, rotation
- WiFi — Safari renders real pages over the emulated BCM4325
- Decrypted third-party apps install over USB and launch
- Real OpenGL ES games. Guest GL traps to the host over a cp15 escape hatch
and renders with a real OpenGL context, then goes to CoreAnimation through
the IOSurface present path — so an app's GL is composited under ordinary
UIKit views. The MBX is not on the path at all. - Root ssh over USB;
lldbon guest processes - The host clipboard writes into the guest pasteboard
- Save and restore a running machine — 86 MB in ~1.1 s
tests/ipod/run-regression.sh, a harness that asserts on what is on the
panel rather than that the process is alive
Doesn't, yet
- 3D is partial. One known app reaches a state where the panel keeps
compositing a stale frame. The missing geometry is provably in the GL colour
buffer and provably absent from the panel, and CA accepts every frame it is
handed (ok=3600, failed=0) — so the signalling layer is ruled out by
measurement. Pacing also judders, while the guest sits at 3.5% CPU. - Audio replays a fragment of a clip ~0.37 s later, one period of the
guest's DMA ring. Ringtones (AAC, not raw PCM) are unexamined. - The
.ipainstall placeholder icon appears, but its progress bar never
fills. - Encrypted App Store binaries cannot run.
- A cosmetic stall in the app launch animation.
New since the last release
- Games render, via the IOSurface present path and a GLES bind fix — a bind CA
refused was destroying the drawable that was working. - An audit of all ~34 device models, and its first two sweeps: guest register
values that reached host memory as unchecked indices or sizes are now bounded. - Multitouch reports at 60 Hz instead of 10 Hz.
imgtools/klog.pyreads the guest kernel log out of RAM; the serial port only
ever shows you iBoot.
History note. The QEMU v8.2.0 → v10.0.2 rebase is now a single commit
instead of 10943 upstream ones, so fork comparisons report a meaningful number.
The original graph is preserved at tag pre-squash-2026-08-04 and branch
qemu-upstream-history — use those for git blame on QEMU's own files.