Rockbox auf dem iPod Video

Rocken ohne Blobs

Die Installation des freien Betriebssystems Rockbox ist an sich kinderleicht, ein praktischer graphischer Installationsassistent erledigt das für die meisten MP3-Player auf Knopfdruck. Dies setzt aber einerseits voraus, dass das fragliche Gerät (bzw. sein Speichermedium) noch funktioniert, und ist andererseits etwas gar unabenteuerlich. Wir wollen uns darum heute anschauen, wie man Rockbox sozusagen «von Hand» auf einen iPod installiert und dabei gänzlich auf proprietäre Software verzichten kann.

Der eigentliche Beweggrund, warum ich mich näher mit dem Thema auseinandersetzen wollte, war der bevorstehende Ausfall der Festplatte in meinem iPod Video. Als Ersatz besorgte ich mir einen iFlash-CF um eine CompactFlash-Karte als Speichermedium verwenden zu können. Nachdem ich den Adapter eingebaut hatte, musste ich feststellen, dass der iPod mit der neuen Speicherkarte nichts anfangen konnte und ich diese zuerst mit iTunes initialisieren musste. Da ich auf meinem PC weder iTunes, noch das dazu nötige Windows installiert haben will, machte ich mich auf die Suche nach einem besseren Weg, die CF-Karte in Betrieb zu nehmen.

Hinweis: In diesem Artikel verwende ich /dev/sdX als Gerätenamen für meine Speicherkarte und /tmp/ipod als Build-Verzeichnis. Diese Werte lassen sich in den folgenden Feldern anpassen:

/dev/

Die erwähnten Werte sollten danach im restlichen Text automatisch ersetzt werden.

Rockbox?

Rockbox, für die, die es nicht kennen, ist ein ein freies Betriebssystem für MP3-Player. Es läuft auf unzähligen verschiedenen Geräten und bietet allerlei Funktionen, die weit über das hinausgehen, was die Geräte normalerweise anbieten. Für mich besonders relevant ist die Unterstützung für Dateien in den Formaten Ogg Vorbis und FLAC. Bei einigen Geräten, wie z.B. dem iPod, ist es mit der originalen Software zudem recht mühsam, Musik drauf zu kopieren – mit Rockbox kein Problem, da sich die Geräte nun als ganz normaler USB-Massenspeicher am PC melden.

Was es braucht

Die Abbildung zeigt den logischen Aufbau eines iPod-Speichermediums.

Wenn wir von einer leeren Speicherkarte ausgehen, müssen wir uns also um drei Dinge kümmern:

Den MBR können wir mit Hausmitteln erstellen, ebenso das Dateisystem auf der Datenpartition; für die Firmwarepartition und den Inhalt des .rockbox-Verzeichnisses auf der Datenpartition brauchen wir Spezialsoftware von Rockbox. In den nächsten Schritten werden wir zuerst die notwendigen Programme kompilieren und danach daraus die Images für den iPod erstellen.

Rockbox kompilieren

Wenn wir Rockbox nicht über den einfachen automatischen Installer installieren wollen, müssen wir in einem ersten Schritt den Quellcode beziehen. In den folgenden Beispielen verwende ich das Verzeichnis /tmp/ipod für die einzelnen Zwischenschritte – das lässt sich ggf. oben in den Artikeloptionen anpassen.

$ mkdir -p /tmp/ipod ; cd /tmp/ipod $ git clone git://git.rockbox.org/rockbox $ cd rockbox

Jetzt haben wir unsere lokale Kopie des Rockbox-Quellcodes und können uns daran machen, diesen zu kompilieren.

Rockbox patchen

In der aktuellen Version von Rockbox muss eines der iPod-spezifischen Hilfsprogramme ein wenig angepasst werden, damit es unsere Ansprüche erfüllen kann. Dazu ist ein kleiner Patch nötig, den wir auf den Quelltext anwenden:

$ curl https://www.ott.net/mach/rockbox-ipod-video/patches/ipod-fw-2048-bytes-no-bootloader.patch | patch -p1

Cross-Compiler

Jetzt brauchen wir einen Cross-Compiler, der Rockbox für die ARM-Architektur des iPod kompilieren kann; Rockbox bringt praktischerweise alles dazu notwendige mit. Wir fangen damit an, zu definieren, wo unsere Daten hingeschrieben werden:

$ export RBDEV_DOWNLOAD=/tmp/ipod/archives $ export RBDEV_PREFIX=/tmp/ipod/target $ export RBDEV_BUILD=/tmp/ipod/build

Danach starten wir das Skript, welches den Cross-Compiler kompiliert:

$ cd tools/ $ ./rockboxdev.sh Download directory : /tmp/ipod/archives (set RBDEV_DOWNLOAD or use --download= to change) Install prefix : /tmp/ipod/target (set RBDEV_PREFIX or use --prefix= to change) Build dir : /tmp/ipod/build (set RBDEV_BUILD or use --builddir= to change) Make options : (set MAKEFLAGS or use --makeflags= to change) Restart step : (set RBDEV_RESTART or use --restart= to change) Target arch : (set RBDEV_TARGET or use --target to change) Select target arch: s - sh (Archos models) m - m68k (iriver h1x0/h3x0, iaudio m3/m5/x5 and mpio hd200) a - arm (ipods, iriver H10, Sansa, D2, Gigabeat, etc) i - mips (Jz47xx and ATJ-based players) r - arm-app (Samsung ypr0) x - arm-linux (Generic Linux ARM: Samsung ypr0, Linux-based Sony NWZ) y - mips-linux (Generic Linux MIPS: AGPTek Rocker) separate multiple targets with spaces (Example: "s m a" will build sh, m68k and arm)

Nun wählen wir a («arm») als Architektur und lassen alles durchkompilieren; auf meinem klapprigen alten Core 2 Duo dauert das etwa eine Viertelstunde.

Wenn alles geklappt hat, können wir den Cross-Compiler in unseren Pfad aufnehmen, damit ihn das restliche Build-System bei Bedarf findet:

$ export PATH=$PATH:/tmp/ipod/target/bin/

Somit haben wir alles, um Rockbox selbst zu kompilieren.

Fehler beim Kompilieren

Bei mir klappt es zur Zeit nicht, den Cross-GCC für Rockbox mit GCC 9 zu kompilieren. Das sieht dann in etwa so aus:

../../gcc-4.4.4/gcc/pretty-print.h: At top level: ../../gcc-4.4.4/gcc/pretty-print.h:310:6: error: ‘cgraph_node’ is not defined as a type 310 | ATTRIBUTE_GCC_PPDIAG(2,3); | ^~~~~~~~~~~~~~~~~~~~ ../../gcc-4.4.4/gcc/pretty-print.h:313:6: error: ‘cgraph_node’ is not defined as a type 313 | ATTRIBUTE_GCC_PPDIAG(2,3); […] make[2]: *** [Makefile:949: tree-mudflap.o] Error 1 make[2]: Leaving directory '/tmp/ipod/build/build-gcc/gcc' make[1]: *** [Makefile:4863: all-gcc] Error 2 make[1]: Leaving directory '/tmp/ipod/build/build-gcc' make: *** [Makefile:739: all] Error 2 /tmp/ipod/rockbox/tools $

Wenn das passiert, dann hilft das Einspielen eines weiteren kleinen Patches:

$ curl https://www.ott.net/mach/rockbox-ipod-video/patches/gcc-4-gcc-9.patch | patch -d /tmp/ipod/build/gcc-4.4.4/ -p1

Danach machen wir weiter mit dem Kompilieren von GCC:

$ cd /tmp/ipod/build/build-gcc/ $ make ; make install

Auch in diesem Fall unbedingt daran denken, den Pfad richtig zu setzen:

$ export PATH=$PATH:/tmp/ipod/target/bin/

Rockbox selbst

Nun da wir den Cross-Compiler haben, können wir Rockbox kompilieren. Wir fangen damit an, uns ein Verzeichnis für die generierten Daten zu erstellen:

$ cd /tmp/ipod/rockbox $ mkdir -p build ; cd build

Danach können wir aus einer langen Liste von Geräten unseren iPod auswählen. Glücklicherweise ist sie ziemlich selbsterklärend:

$ ../tools/configure Using temporary directory /tmp Enter target platform: ==Archos== ==iriver== ==Apple iPod== 0) Player/Studio 10) H120/H140 20) Color/Photo 1) Recorder 11) H320/H340 21) Nano 1G 2) FM Recorder 12) iHP-100/110/115 22) Video 3) Recorder v2 13) iFP-790 23) 3G […]

Für den iPod Video wählen wir Option 22.

Platform set to ipodvideo Build (N)ormal, (A)dvanced, (S)imulator, (B)ootloader, (C)heckWPS, (D)atabase tool, (W)arble codec tool: (Defaults to N)

Dann wählen wir N für ein «normales» Build.

Normal build selected Using source code root directory: /tmp/ipod/rockbox Using arm-elf-eabi-gcc 4.4.4 (404) Using arm-elf-eabi-ld 2.20.1.20100303 Detected make GNU Make 4.2.1 Automatically selected arch: arm (ver 4) Created Makefile

Nun ist alles bereit und wir können mit dem eigentlichen Kompilieren loslegen:

$ make

Das dauert wieder eine Weile, bei mir gut 12 Minuten. Danach lassen wir uns ein Archiv mit den benötigten Rockbox-Dateien erstellen:

$ make tar

Das sollte nach ein paar Sekunden fertig sein. Jetzt brauchen wir noch zwei kleine Zusatzprogramme für den iPod:

$ make -C ../rbutil/ipodpatcher/ […] $ make -C ../tools/ ipod_fw

Nun haben wir für den Moment alles, was wir an Software brauchen.

Welches Modell?

Bevor wir uns an die Speicherkarte machen können, müssen wir noch eine kleine aber entscheidende Frage klären: Welchen iPod haben wir überhaupt vor uns? Auch wenn sie sich äusserlich nicht unterscheiden, vom iPod Video gibt es (mindestens) zwei verschiedene Ausführungen. Beide haben die Modellbezeichnung «A1136», eines rechnet aber mit Sektoren à 512 Bytes, beim anderen sind es 2048 Bytes. Die Unterschiede bei der Installation sind zwar klein, aber doch relevant.

Glücklicherweise können wir mit den Werkzeugen von Rockbox herausfinden, welche Sektorgrösse unser iPod verwendet; das Programm muss als root ausgeführt werden. So sieht ein Modell mit 512 Bytes aus:

$ ../rbutil/ipodpatcher/ipodpatcher -l ipodpatcher 45a9b54f24-191202 (C) Dave Chapman 2006-2009 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] Read XML info (4 bytes) [INFO] Ipod found - Photo/Color ("winpod") - /dev/sdc [INFO] Reading partition table from /dev/sdc [INFO] Sector size is 512 bytes […]

Und so eines mit 2048 Bytes:

$ ../rbutil/ipodpatcher/ipodpatcher -l ipodpatcher 45a9b54f24-191202 (C) Dave Chapman 2006-2009 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] Read XML info (9692 bytes) [INFO] Ipod found - Photo/Color ("winpod") - /dev/sdc [INFO] Reading partition table from /dev/sdc [INFO] Sector size is 2048 bytes […]

Wir merken uns diesen Wert für später. Falls das alte Speichermedium im iPod gar nicht mehr funktioniert, können wir den Wert auf diese Art nicht auslesen. Im diesem Fall hilft einfach ausprobieren – entweder die Anleitung für 512 Bytes oder die für 2048 Bytes sollte funktionieren.

Die Speicherkarte

Nun können wir uns daran machen, Rockbox auf die Speicherkarte zu schreiben. Wir fangen mit dem einfachsten Schritt an, der Partitionstabelle im MBR.

Partitionen

Wenn man die Speicherkarte von iTunes initialisieren lässt, werden zwei Partitionen erstellt: eine Firmwarepartition, auf der das Betriebssystem und allerlei anderer Kram von Apple unterkommt, und eine Datenpartition für die Musik. iTunes verwendet dabei 80 MB für die erste Partition – das können wir besser.

Das Image das wir oben erstellt haben ist nämlich (fast) alles, was auf die erste Partition muss, die Grösse der Partition hängt also lediglich von der Grösse des Images ab. Wir lesen diese folgendermassen aus:

$ stat -c %s rockbox.ipod 807828

Mein Firmware-Image ist also 807828 Bytes gross. Dazu kommen noch ein paar Bytes für den Header, das Verzeichnis der Firmware-Partition und ggf. weitere Images (siehe Abbildung), mit 2 MB (2097152 Bytes) sollten wir auf der sicheren Seite sein. Bei einer Blockgrösse von 512 Bytes heisst das, wir brauchen mindestens 2097152 / 512 = 4096 Blöcke auf der Speicherkarte.

Der MBR selber braucht auch noch ein wenig Platz auf der Karte, der iPod erwartet darum die erste Partition bei Sektor 63. Um die Partitionen zu erstellen, verwende ich sfdisk, weil sich das auf einfache Art mit Skripten steuern lässt. Das Skript für unsere Karte sieht dann so aus:

label: dos unit: sectors start=63, size=4096, type=0 start=4159, type=b

Falls die erste Partition grösser sein soll, muss der Anfang der zweiten Partition entsprechend nach hinten verschoben werden.

Wir speichern das Skript als /tmp/ipod.script und führen es mit sfdisk aus (dieser Befehl muss als root ausgeführt werden):

# sfdisk /dev/sdX < /tmp/ipod.script Checking that no-one is using this disk right now ... OK […] The partition table has been altered. Syncing disks.

Wenn alles geklappt hat, haben wir nun die gewünschten zwei Partitionen auf der Karte. Wir können uns die neue Partitionstabelle anzeigen lassen:

$ sfdisk -l /dev/sdX […] Device Boot Start End Sectors Size Id Type /dev/sdX1 63 4158 4096 2M 0 Empty /dev/sdX2 4159 30668799 30664641 14.6G b W95 FAT32

Damit wäre die Karte bereit für unsere Images und Daten.

Firmware

Auf der Firmwarepartition erwartet der iPod, sein Betriebssystem zu finden. Zusätzlich brauchen wir einen vorgegebenen Header und eine Art Inhaltsverzeichnis, damit das Gerät beim Einschalten herausfindet, wo genau es das Image für das System findet.

Wie die Abbildung zeigt, können allerlei verschiedene Images in die Firmwarepartition geladen werden. Rockbox unterstützt mindestens vier verschiedene Kombinationen von Images mit ihren jeweiligen Vor- und Nachteilen. Da wir keine Apple-Firmware starten wollen, orientieren wir uns an Option 4 («OSOS contains only Rockbox»); leider unterstützt der iPod Video das nicht genau so, weshalb wir zusätzlich noch ein zweites, leeres Pseudo-Image mit in die Firmware verpacken müssen. Konkret sieht das dann so aus:

Das Rockbox-Image haben wir oben bereits kompiliert, es heisst rockbox.bin und liegt im build-Verzeichnis. Das Pseudo-Image können wir uns von Rockbox generieren lassen. Zuerst bauen wir dazu ein Firmware-Image für den ipod5g:

$ ../tools/scramble -ipod5g rockbox.bin temp.img

Leider fehlen dem Image ein paar leere Bytes am Ende. Auf dem iPod wäre das egal, da wir aber mit dem Image weiterarbeiten, hängen wir diese noch an:

$ dd if=/dev/zero of=temp.img oflag=append conv=notrunc bs=1024 count=1

An sich sollten wir dieses Image nun auf den iPod kopieren können und wären fertig. Leider erstellt scramble zur Zeit aber Images, die nur auf iPods mit 512 Bytes pro Sektor funktionieren (und auch da nicht ganz korrekt), wir begnügen uns also damit, aus dem Image die leere Partition zu klauen. Den Dateinamen können wir dabei nicht wählen, ipod_fw hat diesen beim Generieren der Images fest verdrahtet:

$ ../tools/ipod_fw -o apple_sw_5g_rcsc.bin -e 1 temp.img

Somit haben wir nun beide Images, die wir brauchen: Rockbox in rockbox.bin und zusätzlich ein leeres apple_sw_5g_rcsc.bin, weil der iPod das so will. Spätestens jetzt müssen wir wissen, ob unser iPod 512 oder 2048 Bytes pro Sektor verwendet (siehe oben).

Modell mit 512 Bytes pro Sektor

Wir erstellen zuerst das Image für die Firmwarepartition aus dem Rockbox-Image:

$ ../tools/ipod_fw -g 5g -o firmware.bin -l rockbox.bin -n Generating firmware image compatible with iPod video

Danach schreiben wir Image (als root) auf die Firmwarepartition:

# dd if=firmware.bin of=/dev/sdc1 bs=512

Modell mit 2048 Bytes pro Sektor

Bei 2048 Bytes pro Sektor sind die Schritte ein wenig komplizierter. Zuerst erstellen wir wieder das Firmware-Image, geben aber zusätzlich die Sektorgrösse an – damit diese Option funktioniert, ist der eingangs erwähnte Patch nötig:

$ ../tools/ipod_fw -s 2048 -g 5g -o firmware.bin -l rockbox.bin -n Generating firmware image compatible with iPod video

Beim Schreiben auf die Speicherkarte müssen wir aufpassen: Der logische Sektor 63 (auf dem unsere Partition anfängt) entspricht auf der Speicherkarte dem Sektor 63 / 512 * 2048 = 252 . Wir müssen also das Image ein wenig nach hinten verschieben:

# dd if=firmware.bin of=/dev/sdc1 bs=512 seek=189

Somit sollte unsere Firmwarepartition nun einsatzbereit sein.

Daten

Auf der Datenpartition erstellen wir ein FAT32-Dateisystem und entpacken die Tar-Datei darauf. Für den ersten Schritt müssen wir wieder wissen, welche logische Sektorgrösse (also 512 oder 2048 Bytes) wir benötigen.

Bei 512 Bytes pro Sektor sieht das so aus (nochmals als root):

# mkfs.vfat -F 32 /dev/sdX2 # mount /dev/sdX2 /mnt/ipod # tar --no-same-owner -C /mnt/ipod/ -xf rockbox.tar # umount /mnt/ipod

Oder, bei 2048 Bytes pro Sektor:

# mkfs.vfat -F 32 /dev/sdX2 -S 2048 # mount /dev/sdX2 /mnt/ipod # tar --no-same-owner -C /mnt/ipod/ -xf rockbox.tar # umount /mnt/ipod

Tadaa. Soll heissen, das war auch schon alles; die Speicherkarte ist jetzt bereit für den Einsatz im iPod.

Wer nicht nur Sokoban spielen möchte, für den ist jetzt der Zeitpunkt gekommen, noch ein wenig Musik auf den iPod zu laden. Meiner ist schon wieder randvoll und wie die Bilder möglicherweise erahnen lassen, dürfte eines meiner nächsten Projekte der Einbau eines neuen Displays sein.