J’ai un iPhone depuis peu (grâce à la très bonne offre idéo de chez Bouygues dont je parlerai dans un autre billet).
Il est nécessaire pour un certain nombre d’opérations d’avoir iTunes, sous Windows ou OSX sur Mac (par ex. pour l’activation initiale ou pour les montées de version du firmware).

Je n’ai aucune machine sous Windows ou OSX, seulement sous Linux. Par contre comme j’ai tout de même besoin d’un Windows pour certaines tâches (par ex. utiliser mon scanner qui n’est pas reconnu sous Linux), j’ai installé un Windows XP sous VirtualBox, et çà marche très bien. J’ai notamment pu installer dessus iTunes et ainsi procéder à l’activation initiale de mon iPhone, ou bien envoyer des MP3 depuis iTunes toujours.

Avec l’apparition d’iTunes 9 et du firmware 3.1, j’ai voulu tenter l’upgrade de l’iPhone depuis VirtualBox. Mal m’en a pris, çà ne fonctionne évidemment pas !

Au démarrage, l’iPhone démarre ainsi et se retrouve bloqué sur ce mode :

iPhone, démarrage en mode recovery - iPhone, activation iTunes

Pour rappel VirtualBox est un outil de virtualisation qui permet de faire tourner sur un système d’opération donné d’autres OS, de manière virtuelle. La reconnaissance des périphériques physiques (par ex. USB) branchés sur la machine hôte fonctionne très bien : ils sont propagés vers le système invité (sélection pour chaque périphérique USB de la propagation manuelle ou automatique vers le système invité).

Toutefois dans le cas d’une mise-à-jour de l’iPhone :

  • iTunes (sous Windows XP) télécharge le nouveau firmware ;
  • l’iPhone reboot pour passer en mode recovery, et est donc déconnecté tant du Windows XP virtualisé que du système Linux ;
  • au redémarrage de l’iPhone, il est reconnu par la machine hôte (ici un Linux Ubuntu 8.10) … ;
  • … mais n’est toutefois pas propagé immédiatement / à temps à la machine invité (le Windows XP sur lequel tourne iTunes) ;
  • la mise-à-jour iTunes (sous Windows XP) tombe en erreur car l’iPhone a disparu ;
  • l’iPhone reste alors bloqué en mode recovery (un rebranchement sous iTunes ne suffit pas à le remettre d’aplomb) ;

Le problème se pose donc sur la phase de reboot : au moment où l’iPhone redémarre en mode recovery, il s’attend à recevoir une information d’iTunes. Mais, ayant redémarré, il a été éjecté de la machine invité, et au reboot n’est reconnu que par la machine hôte (Linux / Ubuntu), qui n’est pas capable de lui donner les infos pour continuer (bravo Apple au passage pour ne pas mettre en place des mécanismes simples et éprouvés …).

Pour réactiver l’iPhone il faut le sortir du mode recovery, à l’aide du logiciel iRecovery .

Remarque 1 : cette manipulation peut également servir sur certains problèmes pouvant survenir lors d’un jailbreak.
Remarque 2 : la même opération peut également se faire sous Windows (voir par exemple ce lien).

Pour ce faire :

  1. Télécharger les sources d’iRecovery depuis ce lien ou depuis celui-ci pour avoir les sources les plus récentes (SVN) (ou voir en fin de billet) ;
  2. Procéder à la compilation d’iRecovery (voir ci-dessous pour les dépendances) ;
  3. Exécuter la commande “iRecovery -s” pour démarrer iRecovery, qui va se connecter à l’iPhone en mode bas-niveau ;
  4. Taper sous iRecovery la commande “printenv“ ;
  5. Vérifier la variable “auto-boot”, qui va vraisemblablement être à “false” ;
  6. Taper : “setenv auto-boot true” pour modifier cette valeur ;
  7. Taper : “saveenv“ ;
  8. Taper : “reboot“ ;

L’iPhone redémarre et n’est plus en mode recovery. Reste à faire la mise-à-jour du firmware depuis un PC nativement sous Windows.

Logs

Compilation d’iRecovery.

Personnellement j’ai eu besoin d’installer libusb et libreadline au préalable en dépendances.

ubuntu:/tmp/iRecovery> sudo apt-get install libusb-dev
(...)
ubuntu:/tmp/iRecovery> sudo apt-get install libreadline5-dev
make linux
gcc irecovery.c -o irecovery -lusb -lreadline
(...)
ubuntu:/tmp/iRecovery> ll
total 72
-rw-r--r-- 1 sergio sergio   913 2009-07-25 00:53 constants.h
-rwxr-xr-x 1 sergio sergio 14612 2009-09-10 10:33 irecovery
-rw-r--r-- 1 sergio sergio  7168 2009-07-25 00:53 irecovery.c
-rw-r--r-- 1 sergio sergio 35146 2009-07-25 00:53 LICENSE
-rw-r--r-- 1 sergio sergio   341 2009-07-25 00:53 Makefile
-rw-r--r-- 1 sergio sergio   770 2009-07-25 00:53 README

Trace de la manipulation sous iRecovery.

Les manipulations effectuées.

ubuntu:/tmp/iRecovery> irecovery -s
iRecovery - Recovery Utility
by westbaer
Thanks to pod2g, tom3q, planetbeing and geohot.

=======================================
::
:: iBoot for n88ap, Copyright 2009, Apple Inc.
::
::	BUILD_TAG: iBoot-596.24
::
::	BUILD_STYLE: RELEASE
::
::	USB_SERIAL_NUMBER: CPID:8920 CPRV:14 CPFM:03 SCEP:02 BDID:00 ECID:000001xxxxxxxxxx IBFL:01 SRNM:[8xxxxxxxxx]
::
=======================================

[FTL:MSG] Apple NAND Driver (AND) RO
[NAND] Found Chip ID 0x3294D79876 on FMI0:CE0
[NAND] Found Chip ID 0x3294D79876 on FMI0:CE1
[NAND] Found Chip ID 0x3294D79876 on FMI1:C8
[NAND] Found Chip ID 0x3294D79876 on FMI1:CE9
[FTL:MSG] FIL_Init            [OK]
[FTL:MSG] BUF_Init            [OK]
[FTL:MSG] FPart Init          [OK]
read new style signature 0x43313132 (line:305)
[FTL:MSG] VSVFL Register  [OK]
[FTL:MSG] VFL Init            [OK]
[FTL:MSG] VFL_Open            [OK]
[FTL:MSG] YAFTL Register  [OK]
[FTL:MSG] FTL_Open            [OK]
Boot Failure Count: 0	Panic Fail Count: 0
Entering recovery mode, starting command prompt
] printenv
  build-style = "RELEASE"
  build-version = "iBoot-596.24"
  config_board = "n88ap"
  loadaddr = "0x41000000"
  boot-command = "fsboot"
  idle-off = "true"
  boot-device = "nand0"
  boot-partition = "0"
  boot-path = "/System/Library/Caches/com.apple.kernelcaches/kernelcache.s5l8920x"
  display-color-space = "RGB888"
  display-timing = "n88"
P bootdelay = "0"
P platform-uuid = <DATA>
P backlight-level = "168"
P auto-boot = "false"
  image-version = "0x3"
  framebuffer = "0x4f00000"
  secure-boot = "0x1"
] setenv auto-boot true
] saveenv
] reboot
] exit

A tout hasard, mon répertoire (sources au 2009-08-22 + binaire compilé sur Ubuntu 8.10 en 32 bits et Ubuntu 9.10 en 64 bits) :