Thursday, 12 March 2009

Linux on My iPod Mini

1. Introduction

Santa got me an iPod Touch for Christmas so my once-cool-but-by-now-somewhat-battered iPod Mini suddenly found itself redundant. Therefore I decided to put Linux on the old girl. Why? Because I can ;-) See the iPod Linux main page for the downloads and comprehensive instructions. In the spirit of this blog I thought I'd document what I did for posterity.

There is an installer that does all of this automatically, but I decided to go for the manual install since I would learn more that way.

In summary...

The first time this is done the following tasks need to be performed:

  1. Backup important stuff (MBR, Apple firmware and music/data files)
  2. Repartition the hard drive to create a new partition for Linux
  3. Format the new partition as ext3
First time, and every time any software needs to be updated, the following tasks need to be performed:

  1. Install/update the boot loader
  2. Install/update the Userland (I'll come to what that is in a minute)
  3. Install/update the Linux kernel
  4. Install/update podzilla 2 and modules (again, I'll come to that soon)
  5. Restart
2. Before Starting

The relevant downloads need to be obtained from http://www.ipodlinux.org/wiki/Manual_Installation#Downloads. In my case these were:

  • Loader 2 - Bootloader with menu
  • ipodpatcher - Utility for installing bootloader into iPod
  • Linux kernel - What it says
  • Userland - Directories and files needed for Linux root filesystem

Instructions for installing podzilla are located at http://www.ipodlinux.org/wiki/Manual_Installation#Installing.2FUpdating_podzilla2_.2B_Modules. In my case I needed:

  • podzilla - The user interface
  • pzmodules - Modules to be loaded by podzilla
  • appearance - Fonts, etc used by podzilla
I put all of these into a directory on my laptop called ~myuser/iPodLinux.

3. Locating The iPod

Before you start you need to know how your PC/laptop identifies your iPod when it is attached. This can be done using the ipodpatcher utility.

Using the ipodcatcher utility

ipodpatcher is a utility that comes from the Rockbox project which will be used to install the new bootloader into the first partition. For now this can be used to identify the iPod type and the device name:
[root@localhost iPodLinux]# chmod +x ipodpatcher
[root@localhost iPodLinux]# ./ipodpatcher --scan
ipodpatcher v3.0 with v3.0 bootloaders - (C) Dave Chapman 2006-2007
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[INFO] Scanning disk devices...
[INFO] Ipod found - 1st Generation Mini ("winpod") - /dev/sdb
[root@localhost iPodLinux]
Here the ipod is a 1st Generation ("1G") iPod Mini and it is mounted on my laptop as /dev/sdb.

4. First Time

The first time this is done it is necessary to:
  1. Backup important stuff (MBR, Apple firmware and music/data files)
  2. Repartition the hard drive to create a new partition for Linux
  3. Format the new partition as ext3
4.1 Backup Important Stuff

4.1.1 Music and Data Files

The music partition's mount point needs to be located:
[root@localhost iPodLinux]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
10G 5.3G 4.3G 56% /
/dev/mapper/VolGroup00-LogVol02
2.0G 371M 1.6G 20% /home
/dev/mapper/VolGroup00-LogVol03
4.1G 1.1G 2.8G 29% /opt
/dev/sda3 190M 20M 161M 11% /boot
tmpfs 1.6G 96K 1.6G 1% /dev/shm
/dev/sda2 31G 23G 8.2G 74% /media/d
/dev/sda1 24G 18G 6.1G 75% /media/System
/dev/sdb2 3.8G 1.4G 2.5G 36% /media/IPOD
[root@localhost iPodLinux]#
Here we see a device /dev/sdb2 mounted as /media/IPOD. This is the FAT32 file system used to store music files and any other data (e.g. Calendar, Contacts, etc):
[root@localhost iPodLinux]# ls -l /media/IPOD/
total 16
drwxr-xr-x 2 rmccallu root 4096 2005-03-10 15:06 Calendars
drwxr-xr-x 2 rmccallu root 4096 2005-03-10 15:06 Contacts
drwxr-xr-x 5 rmccallu root 4096 2005-03-10 15:06 iPod_Control
drwxr-xr-x 2 rmccallu root 4096 2005-03-10 15:06 Notes
[root@localhost iPodLinux]#
My Calendars, Contacts and Notes directories were essentially empty. So I only needed to back up the iPod_Control directory (where the music is kept by the Apple firmware):
[root@localhost iPodLinux]# tar czvf iPod_Control.tar.gz /media/IPOD/iPod_Control/
tar: Removing leading `/' from member names
/media/
IPOD/iPod_Control/
/media/
IPOD/iPod_Control/Device/
/media/
IPOD/iPod_Control/Device/SysInfo
/media/
IPOD/iPod_Control/Device/Preferences
/media/
IPOD/iPod_Control/Device/_show_voltage
etc...

/media/
IPOD/iPod_Control/Music/f48/09 Lochanside 1.m4a
/media/
IPOD/iPod_Control/Music/f48/10 Rolling Home 1.m4a
/media/
IPOD/iPod_Control/Music/f49/
[root@localhost iPodLinux]#
4.1.2 Firmware Partition

Here ipodpatcher is used again, this time to backup the firmware partition to a file called bootpartition.bin:
[root@localhost iPodLinux]# ./ipodpatcher -r bootpartition.bin
ipodpatcher v3.0 with v3.0 bootloaders - (C) Dave Chapman 2006-2007
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[INFO] Scanning disk devices...
[INFO] Ipod found - 1st Generation Mini ("winpod") - /dev/sdb
[INFO] Reading partition table from /dev/sdb
[INFO] Sector size is 512 bytes
[INFO] Part Start Sector End Sector Size (MB) Type
[INFO] 0 63 80324 39.2 Empty (0x00)
[INFO] 1 80325 7984304 3859.4 W95 FAT32 (0x0b)
[INFO] Ipod model: 1st Generation Mini ("winpod")
[INFO] Writing 80262 sectors to output file
[INFO] Done.
[INFO] Partition extracted to bootpartition.bin.
[root@localhost iPodLinux]#
This creates a file bootpartition.bin that can be compressed:


[root@localhost iPodLinux]# gzip bootpartition.bin
[root@localhost iPodLinux]#
4.1.3 MBR (Its a WinPod)

Now the MBR is backed up, just in case...
[root@localhost iPodLinux]# dd if=/dev/sdb of=ipod_mbr_backup bs=512 count=1
1+0 records in
1+0 records out
512 bytes (512 B) copied, 8.765e-05 s, 5.8 MB/s
[root@localhost iPodLinux]#
I then copied these three files to another directory well out of harm's way before continuing...

4.2 Repartitioning the Hard Drive (WinPods only) - hold onto your hat!

I should explain that the iPod's disk comes with two primary partitions configured: The first partition, usually a few 10's of MB, contains the Apple firmware, while the much larger second partition, occupying the remainder of the disk, is where music and data files are stored.

The first partition needs to be shrunk as much as we dare and then a third partition needs to be created in the resulting gap between the first and second partitions. On this third partition an ext3 filesystem will be created for Linux.

Unmount iPod partition:
[root@localhost iPodLinux]# umount /dev/sdb2
[root@localhost iPodLinux]#
(Recall /dev/sdb2 was the file used for the /media/IPOD mount point - we saw this earlier)

Start fdisk:


[root@localhost iPodLinux]# fdisk /dev/sdb

Command (m for help):
Take a look at partition table:


Command (m for help): p

Disk /dev/sdb: 4095 MB, 4095737344 bytes
255 heads, 63 sectors/track, 497 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x20202020

Device Boot Start End Blocks Id System
/dev/sdb1 1 5 40131 0 Empty
/dev/sdb2 6 497 3951990 b W95 FAT32

Command (m for help):
From this we can see that my disk has cylinders that are 8MB in size (Units = cylinders of 16065 * 512 = 8225280 bytes). Also the firmware partition (/dev/sdb1) starts at cylinder 1 and ends at cylinder 5 (/dev/sdb1 1 5) making it 5 cylinders big i.e. 5 * 8 MB = 40 MB.

The firmware partition has to be shrunk to a whole number of cylinders that is large enough to hold the Apple firmware. I shrank mine to end at cylinder 2 (making it 2 x 8MB = 16 MB) and then created the new partition for linux at cylinders 3 to 5 (making that one 3 x 8MB = 24MB) as recommended on the ipodlinux web site for devices with a 5 cylinder firmware partition.

Actually you can't shrink a partition, it needs to be deleted and re-created:
Command (m for help): d
Partition number (1-4): 1
Warning: partition 1 has empty type

Command (m for help):
Recreate it with smaller size:


Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-497, default 1): 1
Last cylinder or +size or +sizeM or +sizeK (1-5, default 5): 2

Command (m for help):
Activate the first partition:


Command (m for help): a
Partition number (1-4): 1

Command (m for help):
Set partition type to 'Empty':


Command (m for help): t
Partition number (1-4): 1
Hex code (type L to list codes): 0
Type 0 means free space to many systems
(but not to Linux). Having partitions of
type 0 is probably unwise. You can delete
a partition using the `d' command.
Changed system type of partition 1 to 0 (Empty)

Command (m for help):
Create the new (3rd) primary partition to fill the space freed up:
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 3
First cylinder (1-497, default 1): 3
Last cylinder or +size or +sizeM or +sizeK (3-5, default 5): 5

Command (m for help):
Review changes:


Command (m for help): p

Disk /dev/sdb: 4095 MB, 4095737344 bytes
255 heads, 63 sectors/track, 497 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x20202020

Device Boot Start End Blocks Id System
/dev/sdb1 * 1 2 16033+ 0 Empty
/dev/sdb2 6 497 3951990 b W95 FAT32
/dev/sdb3 3 5 24097+ 83 Linux

Partition table entries are not in disk order

Command (m for help):
(Hey, how did it know it was a 'Linux' partition?)

At this point the ipodlinux web site says (and I paraphrase here for a 4GB iPod):
Keep in mind that this is for a 4GB Mini1G iPod; for other iPod versions, cylinder numbers may vary.

* Ensure that sda1 starts at cylinder 1.
* The end cylinder of sda1 is one less than the start cylinder of sda3.
* The end cylinder of sda3 is one less than the start cylinder of sda2.
* Each partition has the same ID as the ones in this table. (0, b, and 83 respectively.)
* Only the first two partitions are marked as bootable.

If it doesn't look right leave fdisk without saving changes ("q" command) and try again.
(Well my big partition was never marked as bootable!)

Now, with steady hand, write the partition table:


Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table.
The new table will be used at the next reboot.
Syncing disks.
[root@localhost iPodLinux]#
That didn't look so great! So I tried:
[root@localhost iPodLinux]# sfdisk -R /dev/sdb
BLKRRPART: Device or resource busy
[root@localhost iPodLinux]#
Ooops!

I tried this:
[root@localhost iPodLinux]# eject /dev/sdb
[root@localhost iPodLinux]#
That seemed to work.

4.3 Format the Partitions

Only the Linux partition needs to be formatted.

4.3.1 Format the Linux partition:
[root@localhost iPodLinux]# mkfs.ext3 /dev/sdb3
mke2fs 1.41.0 (10-Jul-2008)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
6024 inodes, 24096 blocks
1204 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=24903680
3 block groups
8192 blocks per group, 8192 fragments per group
2008 inodes per group
Superblock backups stored on blocks:
8193

Writing inode tables: done
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 39 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
[root@localhost iPodLinux]#
4.3.2 Disable filesystem checks for the ext3 partition:


[root@localhost iPodLinux]# tune2fs -c 0 /dev/sdb3
tune2fs 1.41.0 (10-Jul-2008)
Setting maximal mount count to -1
[root@localhost iPodLinux]#
Since the music partition wasn't written over, it isn't necessary to format it and recreate the Folder Structure on it.

5. Every Time

The first time, and every time any software needs to be updated, the following tasks need to be performed:
  1. Install/update the boot loader
  2. Install/update the Userland
  3. Install/update the Linux kernel
  4. Install/update podzilla 2 and modules
  5. Restart
5.1 Installing/Updating the Bootloader

The ipodloader2 needs to be extracted from its archive and then our friend ipodpatcher is used to patch it to the first partition:
[root@localhost iPodLinux]# tar xzvf Ipodloader2-2.6.tar.gz
loader.bin
bin/
bin/getLoader2Args
[root@localhost iPodLinux]#
[root@localhost iPodLinux]# ./ipodpatcher -ab loader.bin
ipodpatcher v3.0 with v3.0 bootloaders - (C) Dave Chapman 2006-2007
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[INFO] Scanning disk devices...
[INFO] Ipod found - 1st Generation Mini ("winpod") - /dev/sdb
[INFO] Reading partition table from /dev/sdb
[INFO] Sector size is 512 bytes
[INFO] Part Start Sector End Sector Size (MB) Type
[INFO] 0 63 32129 15.7 Empty (0x00)
[INFO] 1 80325 7984304 3859.4 W95 FAT32 (0x0b)
[INFO] 2 32130 80324 23.5 Linux (0x83)
[INFO] Ipod model: 1st Generation Mini ("winpod")
[INFO] Moving images to create room for new firmware...
[INFO] Reading original firmware...
[INFO] Wrote 3458048 bytes to firmware partition
[INFO] Bootloader loader.bin written to device.
[root@localhost iPodLinux]#
5.2 Installing/Updating the Userland

The Userland is the folder structure and files that is placed into the root of the ext3 filesystem.

A directory needs to be created to use for mounting the Userland (this only needs to be done the first time - hopefully it will be automounted every time thereafter):
[root@localhost iPodLinux]# mkdir /media/ipoduserland
[root@localhost iPodLinux]# mount -w /dev/sdb3 /media/ipoduserland
Now extract the Userland:


[root@localhost iPodLinux]# cd /media/ipoduserland
[root@localhost ipoduserland]# tar xzvf ~myuser/iPodLinux/Ipod_fs_220606.tar.gz
bin/
bin/[
bin/dd
bin/cp
bin/df
etc...
tar: var/lock: implausibly old time stamp 1904-01-01 00:00:00
tar: var: implausibly old time stamp 1904-01-01 00:00:00
[root@localhost ipoduserland]#
Note: ignore errors about old timestamps.

(Hmmmmmmm. I noticed that these files have ownership 1000:users not root:root...)

Something else is required from the bootloader archive:
[root@localhost ipoduserland]# cd bin
[root@localhost bin]# cp ~myuser/iPodLinux/bin/getLoader2Args .
[root@localhost bin]# chmod +x getLoader2Args
5.3 Installing/Updating the Kernel

Install the linux kernel into the root of the ext3 filesystem:
[root@localhost bin]# cd ~myuser/iPodLinux/
[root@localhost iPodLinux]# gunzip Linux-2.4.32-ipod2-cc.bin.gz
[root@localhost iPodLinux]# cd /media/ipoduserland/
[root@localhost ipoduserland]# cp ~myuser/iPodLinux/Linux-2.4.32-ipod2-cc.bin ./linux.bin
5.4 Installing/Updating podzilla2 + Modules

Finally install the files required by podzilla:
[root@localhost iPodLinux]# cd /media/ipoduserland/bin/
[root@localhost bin]# tar xzvf ~myuser/iPodLinux/podzilla2.tar.gz
podzilla
[root@localhost bin]#
(Hmmmmmmm. I notice that these files have ownership 11129:wheel not root:root...)


[root@localhost iPodLinux]# cd /media/ipoduserland/usr/lib/
[root@localhost lib]# tar xzvf ~myuser/iPodLinux/pzmodules.tar.gz
about/
about/about.mod.o
about/Module
etc..
wumpus/Module
wumpus/wumpus.mod.o
[root@localhost lib]#
(Hmmmmmmm. I notice that these files have ownership 11129:wheel not root:root...)


[root@localhost iPodLinux]# cd /media/ipoduserland/usr/share/
[root@localhost share]# tar xzvf ~myuser/iPodLinux/appearance.tar.gz
fonts/
fonts/6x13.fff
fonts/Sabine_Doscbthm_Smallcaps.fnt
fonts/GPalatino-12.fnt
etc...
schemes/red.cs
schemes/gameboy.cs
[root@localhost share]#
(Hmmmmmmm. I notice that these files have ownership 11129:wheel not root:root...)


[root@localhost share]# cd /media/ipoduserland/etc
[root@localhost etc]# mkdir podzilla
[root@localhost etc]# cd ../bin
[root@localhost bin]# chmod +x podzilla
6. Take it for a Spin

Reboot the iPod: Press the keys MENU and SELECT at the same time and hold for about five seconds.

You will see an Apple logo. I unplugged it from my laptop at this point (No, I didn't eject it first!).

I then saw a menu with the following items:
Apple OS
iPodLinux
Disk Mode
Sleep
There is a title bar that is obviously supposed to identify the version of the boot loader but for me it was garbled so I couldn't read it.

First I selected 'Apple OS' to check that I could still visit the old country. The screen went blank for about 7 secs (for a moment I thought I had bricked it). Then the familiar Apple menu screen comes on. I played a song or two. It seemed to work.

Then I rebooted again and this time selected 'iPodLinux'. Lots of stuff scrolled rapidly past on screen - it looked like it might have been a Linux startup.

Then I got this menu:
Extras
File Browser
Settings
Run...
Power

On the first boot, on all the menus, the selected item has the upper half of its text not visible. But this problem seemed to go away with subsequent boots.

But, hey, it seems to work!

No comments: