These days mounting an iPod/iPhone/iPad on a Linux PC is an automatic task and all the synchronization operations, such as the music sync with Rythmbox, are supported or at least partially supported.
The communication with these devices can take place thanks to the libimobiledevice library with the help of fuse (filesystem in userspace) and several other libraries and applications. For a clearer picture of the involved libraries you can have a look at this software stack diagram.
Unfortunately, having the same functionality in a Linux embedded device such as a Set-Top-Box or a Digital Receiver is not easy because all the applications are part or depend strongly on GNOME or KDE that normally are not available in these systems.
However, all the libraries can be cross-compiled allowing to mount an iPod/iPhone/iPad as a storage device.
Of course, if you want to synchronize your data such as music or videos, you’ll have to develop your own application or port an existing one.
In this post I focus only on how to compile all the required libraries for mounting an iPod/iPhone/iPad as a storage device.
If the Set-Top-Box have a media player with the required codecs, they will be able, at least, to play the content.
Requirements
Fuse needs a kernel driver that is already included in the mainline kernel. In the kernel configuration you find this option under the Filesystem menu. You can compile it as a module or in-kernel. If you choose the former, the module will be called fuse.ko.
Environment configuration
Suppose that we want to install all the libraries in /mnt/target/usr/local.
/mnt/target is the top directory of the target’s filesystem that could be mounted via NFS.
Assume that the cross-toolchain (compiler, linker…) is already in your path.
Set the following environment variables:
$ export PREFIX=/mnt/target/usr/local
$ export HOST=sh4-linux
$ export BUILD=i386-linux
$ export LD_LIBRARY_PATH=$PREFIX/lib
$ export PKG_CONFIG_PATH=$LD_LIBRARY_PATH/pkgconfig
libusb
Package: libusb-1.0.8.tar.bz2
This package is required by libimobiledevice.
$ ./configure --build=$BUILD --host=$HOST --prefix=$PREFIX --disable-static --disable-log
$ make
$ make install
libplist
Package: libplist-1.3.tar.bz2
This package is required by libimobiledevice.
The compilation of libplist is different because it uses cmake.
Create a file toolchain.cmake with the following contents. Modify the cross-compiler variables according to your path:
# this one is important
SET(CMAKE_SYSTEM_NAME Linux)
#this one not so much
SET(CMAKE_SYSTEM_VERSION 1)
# specify the cross compiler
SET(CMAKE_C_COMPILER /opt/STM/STLinux-2.3/devkit/sh4/bin/sh4-linux-gcc)
SET(CMAKE_CXX_COMPILER /opt/STM/STLinux-2.3/devkit/sh4/bin/sh4-linux-g++)
# where is the target environment
SET(CMAKE_FIND_ROOT_PATH /mnt/target/usr/local)
# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
Then create the build directory, compile and install:
$ mkdir build
$ cd build
$ cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake ..
$ make DESTDIR=$PREFIX install
usbmuxd
Package: usbmuxd-1.0.4.tar.bz2
This package is needed by libimobiledevice.
usbmux uses cmake too. Therefore, the procedure is the same as liplist:
Create the file toolchain.cmake with the same contents as with libplist-1.3 or just copy it to the current directory usbmuxd-1.0.4.
$ cd usbmuxd-1.0.4
$ cp ../libplist-1.3/toolchain.cmake .
Then create the build directory, compile and install:
$ mkdir build
$ cd build
$ cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake ..
$ make DESTDIR=$PREFIX install
libgpg-error
Package: libgpg-error-1.7.tar.gz
This package is needed by libgcrypt.
$ ./configure --build=$BUILD --host=$HOST --prefix=$PREFIX
$ make
$ make install
libgcrypt
Package: libgcrypt-1.4.6.tar.gz
This package is needed by gnutls
$ ./configure --build=$BUILD --host=$HOST --prefix=$PREFIX --with-gpg-error-prefix=$PREFIX
Note: I didn’t need to modify these Makefiles when using an updated STLinux2.3. But if you haven’t done an ‘stmyum update’ lately, maybe you’ll need to modify them.
Edit the Makefile:
Remove from the variables DIST_SUBDIRS and SUBDIRS the directory ‘tests’
Edit the src/Makefile:
Set the following variables to the given values:
GPG_ERROR_CFLAGS = /mnt/target/usr/local/include
GPG_ERROR_CONFIG =
GPG_ERROR_LIBS = /mnt/target/usr/local/lib/libgpg-error.so.0.7.0
libgcrypt_la_LIBADD =
../cipher/libcipher.la
../random/librandom.la
../mpi/libmpi.la
/mnt/target/usr/local/lib/libgpg-error.so.0.7.0
Compile and install:
$ make
$ make install
libtans1
Package: libtasn1-2.7.tar.gz
This package is needed by libimobiledevice.
$ ./configure --build=$BUILD --host=$HOST --prefix=$PREFIX
$ make
$ make install
gnutls
Package: gnutls-2.8.6.tar.bz2
This package is needed by libimobiledevice.
$ ./configure --build=$BUILD --host=$HOST --prefix=$PREFIX
--with-libgcrypt-prefix=$PREFIX --enable-large_files --disable-gtk-doc-html
Edit the files src/Makefile, doc/Makefile and doc/examples/Makefile:
Set LDFLAGS to this value:
LDFLAGS = /mnt/target/usr/local/lib/libgcrypt.so /mnt/target/usr/local/lib/libgpg-error.so
$ make
$ make install
libimobiledevice
Package: libimobiledevice-1.0.2.tar.bz2
$ ./configure --build=$BUILD --host=$HOST --prefix=$PREFIX
libusbmuxd_CFLAGS="-I$PREFIX/include" libusbmuxd_LIBS="-L$PREFIX/lib"
libgnutls_CFLAGS="-I$PREFIX/include" libgnutls_LIBS="-L$PREFIX/lib"
libtasn1_CFLAGS="-I$PREFIX/include" libtasn1_LIBS="-L$PREFIX/lib"
libplist_CFLAGS="-I$PREFIX/include" libplist_LIBS="-L$PREFIX/lib"
libglib2_CFLAGS="-I$PREFIX/include -I$PREFIX/lib/glib-2.0/include" libglib2_LIBS="-L$PREFIX/lib"
--without-swig
Edit the file tools/Makefile:
Set LDFLAGS to this value:
LDFLAGS = /mnt/target/usr/local/lib/libgcrypt.so /mnt/target/usr/local/lib/libgpg-error.so /mnt/target/usr/local/lib/libplist.so /mnt/target/usr/local/lib/libtasn1.so /mnt/target/usr/local/lib/libusbmuxd.so /mnt/target/usr/local/lib/libgnutls.so
Compile and install:
$ make
$ make install
fuse
Package: fuse-2.8.4
$ ./configure --build=$BUILD --host=$HOST --prefix=$PREFIX
$ make
$ make DESTDIR=$PREFIX install
ifuse
Package: ifuse-1.0.0.tar.bz2
$ ./configure --build=$BUILD --host=$HOST --prefix=$PREFIX
CFLAGS=-D_FILE_OFFSET_BITS=64
libimobiledevice_CFLAGS="-I$PREFIX/include" libimobiledevice_LIBS="-L$PREFIX/lib"
libglib2_CFLAGS="-I$PREFIX/include/glib-2.0 -I$PREFIX/lib/glib-2.0/include" libglib2_LIBS="-L$PREFIX/lib"
libgthread2_CFLAGS="-I$PREFIX/include" libgthread2_LIBS="-L$PREFIX/lib"
libfuse_CFLAGS="-I$PREFIX/include" libfuse_LIBS="-L$PREFIX/lib"
Edit the file src/Makefile:
Set libfuse_LIBS to this value:
libfuse_LIBS = -L/mnt/target/usr/local/lib -lfuse -limobiledevice -lgnutls -lplist -lusbmuxd
Compile and install:
$ make
$ make install
Mounting the device
At this point you should be able to mount your iPod/iPhone as a storage device. Some iPods can have a partition, like /dev/sda1, formatted as VFAT of HFS+, depending on where you use it. Some others, like the iPod shuffle, doesn’t have a partition, so you’ll see them as /dev/sda.
Assuming that you want to mount it in /media/ipod, that it has partition /dev/sdb1, and it’s formatted in VFAT, you can mount it as a normal storage device:
$ mount -t vfat -o usefree /dev/sdb1 /media/ipod
For HFS+ is the same. Notice that your kernel must be compiled for supporting this filesystem:
$ mount -t hfsplus -o ro /dev/sdb1 /media/ipod
Now you can browse in /media/ipod and you’ll see the contents of your iPod’s filesystem!
References
Hi,
Thanks for your information and it’s very useful.
However, when i tried to configure libimobiledevice, i meet the error shown as below:
checking consistency of all components of python development environment… no
configure: error:
Could not link test program to Python. Maybe the main Python library has been
installed in some non-standard library path. If so, pass it to configure,
via the LDFLAGS environment variable.
Example: ./configure LDFLAGS=”-L/usr/non-standard-path/python/lib”
============================================================================
ERROR!
You probably have to install the development version of the Python package
for your distribution. The exact name of this package varies among them.
============================================================================
Do i have to compile any other sources like python2.6-dev?
Really appreciate your help.
Hi,
iirc, when I did the procedure in the post I already had Python installed (I compiled the source following this procedure). So, yes, you seem to need the Python development package. The mentioned procedure could solve your problem, or if you’re using a Linux distro that supports opkg or the like you could simply do opkg install package-name
Regards.
I have installed python2.7 by cross-compiling, but the error still exists. Do i have to install python2.7-dev? Appreciate your help.
May be the problem is that the version of libimobiledevice is newer than the one I used. The newer version that you’re using is trying to link or even run a test for checking that Python is present, but since you’re cross-compiling, the test won’t work in your host. So may be the best thing you could do is to comment in the configure file this check and set to yes the variable used for saving the result of the test for avoiding future complains. Let’s hope this work.
i had same problem, i installed python2.6-dev and run again ./configure , error disappeared 😀
[i have been using ubuntu 10.04 ]