Greetings all, I have once again found myself wishing someone else had written up this mini-hell I had to go through just to use my shiny new toy the way I want to, so once again I have written it up for posterity. I did use a mac to jailbreak my iPhone G3, but everything else I detail here I was able to do using my home wifi network, and my Debian desktop. Please enjoy, and feel free to email me if you have any questions or comments!
Now because there is a lot of out-of-date and incorrect info out there, and it was a major point of contention for me, let me just throw some stats out there: This is an 16 GB iPhone G3 (black) running firmware 2.2 (5G77) on the AT&T 2.9 network. The exact model is MB704LL. I am running Debian unstable and updated today, February 7th. I used gtkpod 0.99.12-3 and libgpod-common 0.7.0-0.1, and gnupod-tools 0.99.7-2. My kernel version (which shouldn’t matter much) is 2.6.26 (custom built from Debian patched kernel source), arch is x86_64.
Step One: It’s a Jail Break!
This is the only step in the process where I wimped out. I tried to find a Linux jailbreak solution, but most of them involved downloading some strange source code from “some dude” (not sourceforge) and building and running it, so instead I went ahead and fetched QuickPwn. It worked great. Another mac option (which appears to support some more advanced options like modifying the image you are going to upload) is Pwnage Tool. I followed the easy directions there and like a charm, my iPhone now has a pineapple shown on startup, and I was able to run Cydia (an iPhone GUI frontend to APT, my favorite package manager!) and install openSSH, perl, and all sorts of other goodies.
NOTE: do *not* try to move your home directoy. Don’t be fooled, my friends, it looks like BSD, smells like BSD, has a broken “ps” which doesn’t work with my favorite flags “-auxwwwfg” like BSD….but it is NOT BSD, it is “crazy apple OS land”. “chsh -s” does not work to change your shell, but you CAN do it by editing /etc/passwd AND /etc/master.password (the shadow file). You CANNOT edit these files to change the mobile user’s home directory, it is hardcoded out the wazoo in all of the apps. It should already be on the largest partition on the device, and if it isn’t, feel free to move it and create a symlink, but do NOT try to actually change the home directory via other methods. While we are at it, make sure your “local” directory where all the apt stuff goes is on the big partition – I think mine went there by default but I don’t remember – I think it goes to /private/var/local (and /var is symlinked to /private/var). Wow, that was a long rant…
Step 1.5: Installing Perl on an iPhone
I wanted to write some perl scripts to do some nifty tasks – one example is, I wanted to run a script like “xkcd.pl 534″ and it would use LWP::UserAgent to fetch that comic from xkcd.com and grep for the alt text, and print it out, since it isn’t possible to see it from mobile Safari. Unfortunately, perl was not in the default repository, but fortunately, I found one that had it. Super huge kudos to the fellow at Coredev for sharing his work – I was not too excited about the idea of trying to build perl myself, on my iPhone.
Step 2: Mount your iPhone
Immediately after jailbreaking your iPhone, you should change the “root” and “mobile” user passwords. I believe the default root password is “alpine”, at least it was on my version.
You probably want to set your iPhone to take a static IP address on your network so you can SSH to it. Some routers let you do this via the wireless router’s GUI, others you just manually pick one and tell the iPhone “use this static address”. I assume a user reading this can figure this part out, or google it, this part of the process was not hard to find guides for.
Once you can ssh into your iPhone, we are ready to set up “sshfs”. Have you ever asked yourself “geez, what *can’t* you do with SSH?” Well, the answer isn’t “mount a remote filesystem”, I can tell you that much. Run the following:
# apt-get install sshfs
SSHFS runs in the userspace, which means you don’t need to use sudo to mount things over SSH. This is good. It does mean, however, that some setup is required. You must add your user to the “fuse” group:
# adduser cmyers fuse
Obviously, substitute your username for “cmyers”. Now here is the tricky part – you must must must log out and back in for this to take effect. you cannot use the same terminal to continue. If you did this in a screen session, in fact, your whole damned screen session, and any windows you subsequently create, will still be using the out of date group list. Use your window manager to start a completely fresh terminal window for this – or hell, even switch to a virtual terminal and log in fresh (Ctrl + Alt + F[1-6]). If you get an error like this:
$ sshfs firstname.lastname@example.org:/var/mobile /media/iphone email@example.com's password: fuse: failed to open /dev/fuse: Permission denied
Then that means you failed to get a “sufficiently new” terminal. Also, pop this and make sure it looks right:
$ ls -lsa /dev/fuse 0 crw-rw---- 1 root fuse 10, 229 2009-01-31 09:52 /dev/fuse $
Note that the “fuse” group has both read and write permissions to /dev/fuse.
Ok, assuming you heeded the bolded advice above (the amount of explanation in my blog is directly proportional to how much time I wasted figuring out that part – so be thankful you don’t have to muck with it!), you should now be ready to mount your iPhone.
The way most iPhone apps in Linux expect your mount to work, you actually mount “/var/mobile/Media” – which is where the iTunes DB and music goes, rather than mounting the home directory itsself (/var/mobile). To do this, run:
$ sudo mkdir /media/iphone $ sudo chown cmyers:cmyers /media/iphone $ sshfs firstname.lastname@example.org:/var/mobile/Media /media/iphone
Obviously, replace the IP address, and “cmyers”, with the appropriate equiavlents. Note also that the actual sshfs command runs as you – after that initial setup, you can mount and unmount the iphone without sudo – joy and hoorah!
Step 3: Teach your iPhone who’s the boss – it ain’t Apple.
It turns out that in the 2.2 update (or maybe 2.1?) Apple decided to change the iTunes DB format quite a bit, including checksumming and crap that is part of the (un)”FairPlay” DRM crap. If you are curious about the details, this is all explained here: Marcan’s Blog. Long story short, you need to tell your iPhone “please, sir, use the old version of the DB”.
Yes, that’s right. Apple added all these extra, super-annoying, redonkulous security measures, but let the configuration option to control whether they are enforced or not in plain-text XML on the device. Apparently, they don’t want to actually stop people from using their jailbroken iPhones with third party apps that can read and write the iTunes DB, just piss them off as much as possible in the process. As the blog explains, simply open the file:
Erm, you did install vim on your iphone, right? I feel sick if I ever use a *nix system which doesn’t have vim on it =) Anyways, edit that file, search for “DBVersion”, and change the value on the line below it to “2″ (instead of, probably, “4″). Now reboot your phone. ( I had a sadface @ rebooting a *nix machine )
Step 4: Exercise super cow powers!
You can fetch down everything you need (I think I got ‘em all…) by running this on your Debian box:
# apt-get install gtkpod gtkpod-aac gnupod-tools
Next go ahead and start up gtkpod. You will have to go to “repository options”, and “add new repository/iPod”. Trust me, you want to get “Music Library” all set up the way you like, THEN copy it to your ipod. Editing directly on the iPod is bad times, I lost some playlists that way. Put in the mount you used (I used “/media/iphone”), and for Model select Touch -> “16GB Touch (black) (xA627)”. Turns out the iTouch and the iPhone 3G are almost identical.
At this point, go ahead and hit “check ipod files”, or try to drag over a playlist or something, and hit “save”. You should see it copy to the iPhone, then say something like “updating DB”. If this works, you are golden, but I think most people will still have one more problem to overcome.
Step 5: Getting the “Firewire Id” (wtf, Apple, it doesn’t have a firewire port!!!)
Apparently, the newer hardware (or firmware, or something) needs some sort of hardware ID to write the DB in a way the iPhone can recognize. Without this step, you may get an error popup along the lines of “Couldn’t find the iPod firewire ID” from gtkpod when it tries to write the iTunes DB, or your iPhone may simply report it has no music on it, when it clearly does according to the storage usage info. To fix this, you follow the info on this wik, under the “determining the Firewire GUID” section. Basically, you must connect your iPhone USING USB, but you don’t have to mount it (because that won’t work), then do the following:
# lsusb -v | less
Note this should be run as root. Search for “iSerial”, and find the one that belongs to the “Apple” device (you don’t have more than one Apple device, do ya?). Record ONLY THE FIRST 16 CHARACTERS of this string, it should look like hex (0 through 9, a through f). Next, edit the “Sysinfo” file (or create it, if it doesn’t exist). Now I have seen different guides claim this file exists at two different paths. One was “/var/mobile/Media/iTunes_Control/Device”, and another was “/var/mobile/Media/iPod_Control/Device”. Chances are, one of these directories will already exist and the other one won’t, so use that. For me, it was “/var/mobile/Media/iTunes_Control/Device”.
$ vim /var/mobile/Media/iTunes_Control/Device/SysInfo
Now add the following to it:
Where the 16 Fs are replaced with your GUID (doubt it matters, but mine had lowercase alphas in it). Some restarting of various programs (force-quit the ipod app on your device, close out gtkpod and reload it), and you should be able to transfer playlists now. Works like a charm for me.
See, wasn’t that easy? =|
I couldn’t have done this without the generous assistance of the “teuf” on irc.freenode.net#gtkpod, All of the libgpod devs, all the folks that contributed to the jailbreaking efforts, and many helpful forum posts on the Ubuntu forums, about both gtkpod and sshfs.