NSLU2-Linux
view · edit · print · history

HowTo.UseUsbIpOnTheNSLU2 History

Hide minor edits - Show changes to markup

July 25, 2007, at 06:56 PM by oo -- Added a note to the binary release of USB/IP 0.1.5
Added lines 3-5:

Note: a binary release of USB/IP 0.1.5 is available and discussed at http://sourceforge.net/forum/forum.php?thread_id=1786127&forum_id=418507

July 20, 2007, at 07:31 PM by fcarolo -- removed false wikilinks
Changed line 6 from:

with an XScale? ARM processor, 10/100 ethernet, and two USB2?.0 host

to:

with an XScale ARM processor, 10/100 ethernet, and two USB2.0 host

Changed line 9 from:

running entirely from the internal flash (8 MBytes?) to fully-fledged

to:

running entirely from the internal flash (8 MBytes) to fully-fledged

Changed line 11 from:

Debian / NSLU2 from a 1 GByte? external flash drive, and the instructions

to:

Debian / NSLU2 from a 1 GByte external flash drive, and the instructions

July 16, 2007, at 05:37 PM by oo --
Changed lines 21-23 from:

Institute of Science and Technology, Japan. The main webpage is at http://usbip.sourceforge.net/.

to:

Institute of Science and Technology, Japan and is now an open source project. The main webpage is at http://usbip.sourceforge.net/.

July 16, 2007, at 05:11 PM by oo -- Changed the URL to the usb/ip project.
Changed lines 22-23 from:

http://usbip.naist.jp/.

to:

http://usbip.sourceforge.net/.

December 12, 2006, at 02:25 PM by Phil Endecott -- Note when you can interrupt the kernel build
Changed lines 113-117 from:

Presumably USB/IP doesn't need all of the .o files from the kernel tree, but it doesn't work if you just copy in the .config file. If there is some make target that does as much as it needs but no more I would love to hear about it.

to:

(Apparently you can interrupt the build process after it has reported "SPLIT", as all of this files that are needed by the USB/IP modules have been built by then.)

December 06, 2006, at 05:01 PM by Phil Endecott -- Simplifiy installation a bit
Changed lines 215-220 from:

I suggest building the arm utilities before the x86 ones, for reasons that I'll explain shortly.

I don't know if these are needed, but they were suggested by some autotools documentation that I read:

to:

First build the x86 utilities:

Changed lines 218-224 from:

$ export CC=arm-linux-gnu-gcc $ export AR=arm-linux-gcc-ar $ export RANLIB=arm-linux-gnu-ranlib $ export AR=arm-linux-gnu-ar $ export AS=arm-linux-gnu-as $ export LD=arm-linux-gnu-ld $ export NM=arm-linux-gnu-nm

to:

$ cd /path/to/usbip-0.1.4-x86/src $ aclocal; autoheader; automake-1.9 -a -c -f; autoconf $ ./configure $ make

  1. make install
Changed lines 225-227 from:

If you do set them, be sure to unsetthem (or just use a new shell) when you compile the x86 code later.

to:

You probably need to do this so that the libraries can be found:

Changed lines 228-231 from:

$ cd usbip-0.1.4-arm/src/ $ aclocal; autoheader; automake-1.9 -a -c -f; autoconf $ ./configure --build=`./config.guess` --host=arm-linux-gnu $ make

to:

echo "/usr/local/lib" >> /etc/ld.so.conf ldconfig

Changed lines 232-236 from:

At this point unfortunately the final link has not been done, due to some libtool trickery. Does anyone know how to get libtool to create the installable files without actually installing them? I could find no alternative to this:

to:

Now for the ARM versions. I don't know if these are needed, but they were suggested by some autotools documentation that I read:

Changed lines 237-243 from:
  1. make install
to:

$ export CC=arm-linux-gnu-gcc $ export AR=arm-linux-gcc-ar $ export RANLIB=arm-linux-gnu-ranlib $ export AR=arm-linux-gnu-ar $ export AS=arm-linux-gnu-as $ export LD=arm-linux-gnu-ld $ export NM=arm-linux-gnu-nm

Changed lines 246-254 from:

This does the final link, but then it copies the code into /usr/local/lib and /usr/local/bin, despite these being arm not x86 executables. This is why I suggest compiling the arm utilities before the x86 ones.

You'll need to move the executables and libraries to /usr/local/* on your slug, taking care to preserve the structure of the symlinks in /usr/local/lib:

to:

If you do set them, be sure to unsetthem (or just use a new shell) before you next compile x86 code.

Changed lines 250-255 from:

pc# files="/usr/local/bin/bind_driver /usr/local/bin/usbip /usr/local/lib/libusbip.*" pc# tar cf usbif-arm-bin.tar $files pc# scp usbif-arm-bin.tar slug:/tmp slug# cd /; tar xf /tmp/usbif-arm-bin.tar pc# rm $files

to:

$ cd usbip-0.1.4-arm/src/ $ aclocal; autoheader; automake-1.9 -a -c -f; autoconf $ ./configure --build=`./config.guess` --host=arm-linux-gnu $ make $ make install DESTDIR=/path/to/tmp-arm-usbip

Changed lines 257-259 from:

You probably need to do this now, so that the dynamic linker looks in /usr/local/lib:

to:

Now copy them over to the slug:

Changed lines 260-261 from:
  1. echo "/usr/local/lib" >> /etc/ld.so.conf
  2. ldconfig
to:

$ cd /path/to/tmp-arm-usbip $ tar cf usbip.tar * $ scp usbip.tar slug:/tmp slug# cd / slug# tar xf /tmp/usbip.tar

Changed lines 267-268 from:

Now build the x86 utilities:

to:

as above:

Changed lines 270-274 from:

$ cd /path/to/usbip-0.1.4-x86/src $ aclocal; autoheader; automake-1.9 -a -c -f; autoconf $ ./configure $ make

  1. make install
to:

slug# echo "/usr/local/lib" >> /etc/ld.so.conf slug# ldconfig

Changed lines 274-281 from:

as above:

echo "/usr/local/lib" >> /etc/ld.so.conf
ldconfig
to:
December 05, 2006, at 09:11 PM by Phil Endecott -- Wiki doesn\'t like \"/\"
Changed line 11 from:

NSLU2 from a 1 GByte? external flash drive, and the instructions

to:

Debian / NSLU2 from a 1 GByte? external flash drive, and the instructions

Changed line 43 from:

NSLU2 on the slug, though much of the procedure will be the same

to:

Debian / NSLU2 on the slug, though much of the procedure will be the same

December 04, 2006, at 03:32 PM by Phil Endecott -- Missing prompts
Changed lines 272-273 from:

echo "/usr/local/lib" >> /etc/ld.so.conf ldconfig

to:
  1. echo "/usr/local/lib" >> /etc/ld.so.conf
  2. ldconfig
December 04, 2006, at 03:29 PM by Phil Endecott -- Create this page (preview still broken)
Added lines 1-344:

How to use USB/IP on an NSLU2

Introduction

The Linksys NSLU2 (aka Slug) is a small, cheap, low-power unit with an XScale? ARM processor, 10/100 ethernet, and two USB2?.0 host ports. It runs Linux and there is an active development community at http://nslu2-linux.org/. Linux possibilities range from small systems running entirely from the internal flash (8 MBytes?) to fully-fledged distributions running from external USB hard disks. In my case I run NSLU2 from a 1 GByte? external flash drive, and the instructions below relate to this system.

USB/IP is a method of transfering USB data between two Linux systems across a network. Specifically it consists of two kernel modules, one for each end of the link, and control utilities. USB peripherals connected to one system can be exported to the other system where they appear as if they were locally connected. USB/IP is not yet included in the official Linux kernel, but is available as a patch. It has been developed by Takahiro Hirofuchi of the Nara Institute of Science and Technology, Japan. The main webpage is at http://usbip.naist.jp/.

Running USB/IP on the slug is an appealing idea. At present a slug can be used to interface many USB peripherals (printers, storage devices, scanners, ...) to a remote PC but in each case specific server software is needed (CUPS, NFS, SANE, ...). Often this works well, but in some cases this server software may make excessive demands on the slug's limited processing power, be complex to install, or otherwise difficult. Other peripherals may not have servers to support remote operation at all. In contrast, USB/IP provides a way to make any peripheral accessible remotely with no additional software to be installed on the slug.

There are, however, some disadvantages to the USB/IP approach. In particular it is not able to make a printer or storage device available to multiple clients simultaneously in the way that CUPS and NFS do. Also, users with non-Linux clients will unable to use USB/IP unless it is ported to their operating system.

This page describes how to compile and use USB/IP between an x86 Linux PC and a slug. It assumes that you're running Debian on the PC and NSLU2 on the slug, though much of the procedure will be the same for other distributions. I also assume that you'll cross-compile the slug code on the PC.

At present I suggest that this is not something that NSLU2 "newbies" attempt to do. In time I expect that the procedure will become simpler and better-documented; when that happens, this should be something that everyone can use.

This is based on USB/IP version 0.1.4.

Prerequisites

Cross-compilation tools

You'll need a cross-compilation environment. The easiest way to get this is to install the pre-compiled packages available from Emdebian (http://www.emdebian.org/tools/crosstools.html); at the time of writing you need to follow the link to "download raw debian packages", rather than using apt-get. These packages will provide you with cross-compiling versions of all of the gcc and binutils programs with the prefix arm-linux-gnu-, and suitable core libraries.

Kernel trees

To compile the USB/IP kernel modules you need kernel source trees in which kernels have been built, one for the PC and one for the slug. You may already have these but if you installed binary kernel packages you need to make one now, as follows:

Get the kernel source. I'm using 2.6.17 on my PC and my slug; it will probably work with other reasonably recent versions, but I don't know for sure:

# apt-get linux-source-2.6.17

Unpack two copies:

$ tar xjf /usr/src/linux-source-2.6.17.tar.bz2
$ mv linux-source-2.6.17 linux-source-2.6.17-x86
$ tar xjf /usr/src/linux-source-2.6.17.tar.bz2
$ mv linux-source-2.6.16 linux-source-2.6.17-arm

Copy over your existing kernel configurations. This will work if you installed Debian kernel image packages:

$ cp /boot/config linux-source-2.6.17-x86/.config
$ scp slug:/boot/config linux-source-2.6.17-arm/.config

Build in the x86 tree:

$ cd /path/to/linux-source-x86
$ make

Build in the arm tree:

$ cd /path/to/linux-source-arm
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnu-

Presumably USB/IP doesn't need all of the .o files from the kernel tree, but it doesn't work if you just copy in the .config file. If there is some make target that does as much as it needs but no more I would love to hear about it.

Other packages

The following packages are also needed, according to the USB/IP README file:

  • hwdata
  • libglib2.0-0
  • libsysfs2

To install hwdata, just "apt-get hwdata" on both the PC and the slug.

In the case of the libraries, for the PC you need to install the libraries and their -dev packages. For the slug, you need to install only the libraries. Then, so that you can cross-compile against these libraries, you need to install the slug versions of the libraries and their -dev packages on the PC using dpkg-cross. (Basically, dpkg-cross takes a -arm package containing /usr/include and /usr/lib files and turns it into a package that you can install on your PC under /usr/arm-linux-gnu/include and /usr/arm-linux-gnu/lib, where the cross compiler looks.)

I find that the easiest way to install slug libraries and -dev packages for cross-compiling is like this:

slug# apt-get -d install libXYZ libXYZ-dev  (download only)
slug# scp /var/cache/apt/arhives/libXYZ*.deb pc:/tmp
slug# apt-get install libXYZ
pc# dpkg-cross -i /tmp/libXYZ*.deb

Remember to apt-get clean on the slug afterwards to get rid of the unwanted .debs.

Compiling USB/IP

Download and unpack

Download the USB/IP tarball from its sourceforge page (http://sourceforge.net/projects/usbip/, then click on "download").

Unpack two copies of it:

$ tar xzf usbip-0.1.4.tar.gz
$ mv usbip-0.1.4 usbip-0.1.4-x86
$ tar xzf usbip-0.1.4.tar.gz
$ mv usbip-0.1.4 usbip-0.1.4-arm

You might like to review the included README files at this point.

Patches

Apply the following fixes to the arm version:

In src/configure.ac, comment out the lines:

AC_FUNC_MALLOC
AC_FUNC_REALLOC

(These tests check if malloc(0) and realloc(0) behave as the GNU C library does. For cross-compilation they can't test this directly so they are pessimistic, and the compilation will fail. But we know that in our case the slug is using the GNU C library.)

In src/include/usbip_common.h, remove the "__attribute__((packed))" at the end of the declaration of struct usb_device.

(This causes the whole structure to be unaligned, which is bad; I think that the author intends just that the fields have no gaps between them, which seems to happen even without this attribute.)

Build kernel modules

Build the x86 kernel modules. There is one directory per kernel version; in my case I use 2.6.17:

$ cd /path/to/usbip-0.1.4-x86/driver/2.6.17/
$ make KSOURCE=/path/to/linux-source-2.6.17-x86

Build the arm kernel modules:

$ cd /path/to/usbip-0.1.4-arm/driver/2.6.17
$ make KSOURCE=/path/to/linux-source-2.6.17-arm ARCH=arm \
CROSS_COMPILE=arm-linux-gnu-
$ scp *.ko slug:/somewhere

Build the utilities

I suggest building the arm utilities before the x86 ones, for reasons that I'll explain shortly.

I don't know if these are needed, but they were suggested by some autotools documentation that I read:

$ export CC=arm-linux-gnu-gcc
$ export AR=arm-linux-gcc-ar
$ export RANLIB=arm-linux-gnu-ranlib
$ export AR=arm-linux-gnu-ar
$ export AS=arm-linux-gnu-as
$ export LD=arm-linux-gnu-ld
$ export NM=arm-linux-gnu-nm

If you do set them, be sure to unsetthem (or just use a new shell) when you compile the x86 code later.

$ cd usbip-0.1.4-arm/src/
$ aclocal; autoheader; automake-1.9 -a -c -f; autoconf
$ ./configure --build=`./config.guess` --host=arm-linux-gnu
$ make

At this point unfortunately the final link has not been done, due to some libtool trickery. Does anyone know how to get libtool to create the installable files without actually installing them? I could find no alternative to this:

# make install

This does the final link, but then it copies the code into /usr/local/lib and /usr/local/bin, despite these being arm not x86 executables. This is why I suggest compiling the arm utilities before the x86 ones.

You'll need to move the executables and libraries to /usr/local/* on your slug, taking care to preserve the structure of the symlinks in /usr/local/lib:

pc# files="/usr/local/bin/bind_driver /usr/local/bin/usbip \
/usr/local/lib/libusbip.*"
pc# tar cf usbif-arm-bin.tar $files
pc# scp usbif-arm-bin.tar slug:/tmp
slug# cd /; tar xf /tmp/usbif-arm-bin.tar
pc# rm $files

You probably need to do this now, so that the dynamic linker looks in /usr/local/lib:

echo "/usr/local/lib" >> /etc/ld.so.conf
ldconfig

Now build the x86 utilities:

$ cd /path/to/usbip-0.1.4-x86/src
$ aclocal; autoheader; automake-1.9 -a -c -f; autoconf
$ ./configure
$ make
# make install

as above:

echo "/usr/local/lib" >> /etc/ld.so.conf
ldconfig

Try it out

On the slug:

Plug in a usb device.

Verify its presence using lsusb or /proc/usb

Start up USB/IP:

# insmod /path/to/usbip.ko
# usbipd -D

Find the device that you want to share, and export it:

# bind_device --list
# bind_device --usbip 1-1.4

On the PC:

Start up USB/IP:

# insmod /path/to/vhch-hci.ko

See what the slug is exporting, and attach to it:

# usbip --list slug
# usbip --attach slug 1-1.4

See that it is attached:

# usbip --port
# lsusb

Now attempt to use the device. If it's a keyboard you can probably just type on it straight away. A mass storage device will probably have created its /dev/sd* node and you can mount it.

Congratulations if you get this far. Please share your experiences.

view · edit · print · history · Last edited by oo.
Based on work by fcarolo, oo, and Phil Endecott.
Originally by Phil Endecott.
Page last modified on July 25, 2007, at 06:56 PM