Fiabiliser la reprise du simulateur après déplacement des homes

This commit is contained in:
Workbench IA committed 2026-09-30 14:38:10 +00:00
1 parent 163e253af8
commit 72c64688f1
6 files changed
+96 -8

No files matched your search

+25
View File
@@ -146,3 +146,28 @@ Debug : `IPOD_QEMU_EXTRA="-d unimp,guest_errors -D ~/ipod-emu/run/int.log"` ; `I
- `-f` efface la session persistée. Ne pas l'utiliser pour vérifier la conservation d'un fichier.
- QEMU et netd sont lancés avec `setsid` pour survivre à la fin du terminal appelant. Le launcher suit netd par PID.
- Un `.deb` 2.x qui dépend d'un jailbreak (bash, etc.) ne marchera pas : aucun shell dans l'image.
## Reprise du 30 septembre 2026 — après déplacement des homes
- Projets retrouvés sous `/srv/homes/iphoneos2/{ipod-emu,qemu-ios}`.
- Bibliothèques QEMU/libslirp et ImageMagick réinstallées dans le conteneur courant ;
lien BootROM 5H11a corrigé en relatif ; commandes accessibles par wrappers dans
`/home/dev/.local/bin`. Ces installations locales ne modifient pas l'image Docker.
- Lanceur adapté aux chemins déplacés, sélection automatique des keymaps via `-L`,
contrôle du démarrage QEMU et du relais, nettoyage du relais même après arrêt QEMU.
`ipod-qmp` prend en compte `IPOD_EMU_HOME`.
- Test sur une copie de NAND dans `ipod-emu/work/reprise-20260930` : boot de l'image
de base en 28 s, Safari et HTTP validés. `push-app HelloEmu.app` copie les deux
fichiers, redémarre sans réinitialiser la NAND ; HelloEmu apparaît ensuite dans
le catalogue `apps`. Le lancement répond toujours `device locked`, écran noir.
Le programme de diagnostic `unlock` retourne 0 sans débloquer le lancement.
Ne pas considérer le lancement après installation comme validé.
- La copie de la session initiale est conservée dans
`work/reprise-20260930/run-session-initiale` ; la session d'origine `run/nand`
n'a pas été modifiée. Les captures et préférences de diagnostic sont dans le
dossier de reprise. Les sessions de test ont été arrêtées.
- Un ancien relais survivant à QEMU occupait 7788 : supprimé avant de refaire le
test. L'ancien code continuait malgré l'échec de redirection ; le nouveau échoue.
- Vérifications : syntaxe Bash/Python, compilation du relais avec `-Wall`,
échec QEMU volontaire détecté immédiatement, port 7788 occupé détecté et QEMU
arrêté, `stop` après échec. Aucun changement des modèles matériels dans cette reprise.
+21
View File
@@ -3,6 +3,27 @@
Émulateur [qemu-ios](https://git.mahtan-melwasul.com/Mahtan/qemu-ios) (branche iPod Touch 2G, N72AP), adapté pour
démarrer **iPhone OS 2.2.1 (5H11a)**. iPhone OS 2.1.1 (5F138) reste disponible. Les outils sont dans `/opt/ios-legacy/bin`.
## Environnement déplacé
Dans le workbench actuel, les projets sont sous `/srv/homes/iphoneos2` :
`ipod-emu` contient les images et les outils, `qemu-ios` contient QEMU.
Les outils utilisés directement depuis `ipod-emu/bin` retrouvent ce dossier ;
le lanceur cherche QEMU dans le dossier voisin et transmet son dossier `pc-bios`
pour retrouver les keymaps VNC après déplacement. `IPOD_EMU_HOME`, `IPOD_QEMU`,
`IPOD_QEMU_DATA` et `IPOD_QMP` permettent de choisir d'autres chemins.
`ipod-qmp` respecte également `IPOD_EMU_HOME` pour le socket de session.
Vérifier les liens symboliques des images après déplacement : le lien de
`images/5H11a/bootrom` doit viser `../5F138/bootrom`, plutôt qu'un ancien home absolu.
Sur Arch, le binaire construit dans cet environnement utilise notamment `pixman`,
`libpng`, `libjpeg-turbo`, `sdl2` et `libslirp` ; les captures PNG utilisent
`imagemagick`. Compiler le relais réseau demande aussi `pkgconf` et `glib2-devel`.
Ces dépendances doivent être présentes dans chaque nouveau conteneur.
Le lanceur échoue explicitement si QEMU ou le relais réseau s'arrête au démarrage.
Un port agent déjà occupé est une erreur : le relais ne poursuit plus sans sa
redirection. `stop` nettoie le relais suivi par PID même si QEMU est déjà arrêté.
## Utilisation
```bash
+3 -1
View File
@@ -52,7 +52,9 @@ def out(body):
def push_app(a, app):
emu_home = os.environ.get("IPOD_EMU_HOME", os.path.expanduser("~/ipod-emu"))
tools_home = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
default_home = tools_home if os.path.isdir(os.path.join(tools_home, "images")) else os.path.expanduser("~/ipod-emu")
emu_home = os.environ.get("IPOD_EMU_HOME", default_home)
run = os.path.join(emu_home, "run")
try:
with open(os.path.join(run, "nand", ".ipod-nand-format")) as f:
+41 -6
View File
@@ -2,8 +2,13 @@
# Lance / arrête l'émulateur iPod Touch 2G (qemu-ios, N72AP).
set -euo pipefail
EMU_HOME="${IPOD_EMU_HOME:-$HOME/ipod-emu}"
QEMU="${IPOD_QEMU:-$HOME/qemu-ios/build/qemu-system-arm}"
TOOLS_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
DEFAULT_EMU_HOME="$HOME/ipod-emu"
# Les outils peuvent être utilisés directement depuis un home de toolchain déplacé.
[ ! -d "$TOOLS_DIR/../images" ] || DEFAULT_EMU_HOME=$(cd "$TOOLS_DIR/.." && pwd)
EMU_HOME="${IPOD_EMU_HOME:-$DEFAULT_EMU_HOME}"
QEMU="${IPOD_QEMU:-$(dirname "$EMU_HOME")/qemu-ios/build/qemu-system-arm}"
QEMU_DATA="${IPOD_QEMU_DATA:-$(dirname "$(dirname "$QEMU")")/pc-bios}"
FW="${IPOD_FW:-5H11a}" # dossier $EMU_HOME/images/<FW>/ : bootrom, nor.bin, nand/ (5H11a = 2.2.1, 5F138 = 2.1.1)
RUN="$EMU_HOME/run"
VNC="${IPOD_VNC:-127.0.0.1:0}" # :0 => port 5900
@@ -62,10 +67,17 @@ start)
img="$EMU_HOME/images/$FW"
[ -d "$img" ] || { echo "Firmware inconnu : $img" >&2; exit 1; }
[ -z "$(pid)" ] || { echo "Déjà lancé (pid $(pid))"; exit 0; }
[ -x "$QEMU" ] || { echo "QEMU introuvable : $QEMU (définir IPOD_QEMU)" >&2; exit 1; }
[ -r "$img/bootrom" ] || { echo "BootROM introuvable : $img/bootrom (vérifier les liens après déplacement du home)" >&2; exit 1; }
[ -x "$EMU_HOME/netd/ipod-netd" ] || { echo "Relais réseau introuvable : $EMU_HOME/netd/ipod-netd" >&2; exit 1; }
"$QEMU" --version >/dev/null
qemu_data_args=()
[ ! -d "$QEMU_DATA/keymaps" ] || qemu_data_args=(-L "$QEMU_DATA")
mkdir -p "$RUN"
if [ $fresh = 1 ] || [ ! -d "$RUN/nand" ] || [ "$(cat "$RUN/fw" 2>/dev/null)" != "$FW" ]; then
rm -rf "$RUN/nand"; cp -rL "$img/nand" "$RUN/nand"; echo "$FW" > "$RUN/fw"
fi
stop_netd
rm -f "$RUN/qmp.sock" "$RUN/serial.log"
mopts=$(cat "$img/machine-opts" 2>/dev/null || true) # ex. ",legacy-nor=off"
if [[ "$mopts" == *",nand-write=on"* ]] &&
@@ -74,21 +86,44 @@ start)
exit 1
fi
nohup setsid "$QEMU" -M "iPod-Touch,bootrom=$img/bootrom,nand=$RUN/nand,nor=$img/nor.bin$mopts" \
-cpu max -m 2G -serial "file:$RUN/serial.log" -serial "unix:$RUN/uart1.sock,server=on,wait=off" \
"${qemu_data_args[@]}" -cpu max -m 2G -serial "file:$RUN/serial.log" -serial "unix:$RUN/uart1.sock,server=on,wait=off" \
-display none -vnc "$VNC" -qmp "unix:$RUN/qmp.sock,server,nowait" \
-pidfile "$RUN/qemu.pid" ${IPOD_QEMU_EXTRA:-} > "$RUN/qemu.log" 2>&1 &
for _ in $(seq 50); do [ -S "$RUN/qmp.sock" ] && break; sleep 0.2; done
qemu_pid=$!
for _ in $(seq 50); do
if ! kill -0 "$qemu_pid" 2>/dev/null; then
echo "Échec du démarrage de QEMU :" >&2
cat "$RUN/qemu.log" >&2
exit 1
fi
[ ! -S "$RUN/qmp.sock" ] || [ -z "$(pid)" ] || break
sleep 0.2
done
if [ ! -S "$RUN/qmp.sock" ] || [ -z "$(pid)" ]; then
kill "$qemu_pid" 2>/dev/null || true
echo "QEMU n'a pas ouvert son socket QMP (voir $RUN/qemu.log)" >&2
exit 1
fi
# réseau : PPP sur l'UART1 -> slirp (NAT, DNS, 127.0.0.1:7788 -> agent de l'iPod)
stop_netd
nohup setsid "$EMU_HOME/netd/ipod-netd" -s "$RUN/uart1.sock" ${IPOD_NETD_FWD:-} > "$RUN/netd.log" 2>&1 &
echo "$!" > "$RUN/netd.pid"
netd_pid=$!
echo "$netd_pid" > "$RUN/netd.pid"
sleep 0.3
if ! kill -0 "$netd_pid" 2>/dev/null; then
echo "Échec du relais réseau :" >&2
cat "$RUN/netd.log" >&2
"$(dirname "$0")/ipod-qmp" -s "$RUN/qmp.sock" quit 2>/dev/null || kill "$qemu_pid"
stop_netd
exit 1
fi
echo "Démarré ($FW) — pid $(pid), VNC $VNC. SpringBoard apparaît en ~1 min."
echo "Logs iOS : $RUN/serial.log"
[ $waitr = 0 ] || wait_ready
;;
wait) wait_ready "${1:-300}" ;;
stop)
p=$(pid) || { echo "Pas lancé"; exit 0; }
p=$(pid) || { stop_netd; echo "Pas lancé"; exit 0; }
"$(dirname "$0")/ipod-qmp" -s "$RUN/qmp.sock" quit 2>/dev/null || kill "$p"
for _ in $(seq 50); do kill -0 "$p" 2>/dev/null || break; sleep 0.2; done
kill -0 "$p" 2>/dev/null && kill -9 "$p"
+4 -1
View File
@@ -59,7 +59,10 @@ def key(q, qcode):
def main():
p = argparse.ArgumentParser(usage=__doc__)
p.add_argument("-s", "--sock", default=os.environ.get("IPOD_QMP", os.path.expanduser("~/ipod-emu/run/qmp.sock")))
tools_home = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
default_home = tools_home if os.path.isdir(os.path.join(tools_home, "images")) else os.path.expanduser("~/ipod-emu")
emu_home = os.environ.get("IPOD_EMU_HOME", default_home)
p.add_argument("-s", "--sock", default=os.environ.get("IPOD_QMP", os.path.join(emu_home, "run", "qmp.sock")))
p.add_argument("action")
p.add_argument("args", nargs="*")
a = p.parse_args()
+2
View File
@@ -556,6 +556,8 @@ static void add_fwd(const char *spec)
}
if (slirp_add_hostfwd(slirp, 0, host, hp, guest, gp) < 0) {
logm("redirection %s impossible (port occupé ?)", spec);
/* Ne pas laisser le client contacter le relais d'une autre session. */
exit(1);
} else {
logm("redirection tcp %s:%d -> iPod:%d", inet_ntoa(host), hp, gp);
}