How to set up an Ethernet over USB connection between the Sharp Zaurus SL-5000D/SL-5500 and a Linux machine.

Google
 
Web www.ruault.com
Version: 1.13, 07/17/2003  Author: Charles-Edouard Ruault

Credits: Thanks to Stuart Lynne for allowing me to distribute Lineo's new driver
  Thanks to the people who sent me remarks and asked questions, they helped me improve this document !

This Document assumes that the Linux machine is running a Linux kernel 2.4.x, with x>=17.
This document describes the setup for a Zaurus ROM version >= 1.10, for older ROMs versions, check this page.
NEW If you're using a kernel version >=2.4.21 then read this.

DISCLAIMER: Use this patch at your own risk, it comes with no warranty !

To get information on specific distributions, follow these links :
Mandrake 8.2
Suse 7.1 and 8.0
Debian
Kernel version >=2.4.21

1) Patch the linux kernel
The patch has been tested against kernel 2.4.17 and up.
I've received patches for some specific kernel version shipped with common distributions, see in the download area listed below if there is one for yours !
Download the patch corresponding to your kernel version from here

Assuming your Linux sources are in /usr/src/linux do the following :
cp usbdnet-2.4.x.patch.gz /usr/src
cd /usr/src
zcat usbdnet-2.4.x.patch.gz | patch -p0

Now reconfigure the kernel to support :
cd /usr/src/linux
make menuconfig
in "Code maturity level options", select "Prompt for development and/or incomplete code/drivers"
in "USB support", section "USB Network adaptors", select (as a module) "USBD Network (Encapsulated) Host-to-Host Link (EXPERIMENTAL)"
Then enter 04dd in USBD Network idVendor and 8004 in USBD Network idProduct

Now rebuild and install the modules ( note : this supposes that a kernel had already been build in this source tree, if it's not the case, do a make bzImage before the make modules ) cd /usr/src/linux && make clean dep modules modules_install.
Make sure that the core usb support is already active in your kernel : modules usbcore and usb-uhci or usb-ohci should be loaded, if not run modprobe usb-uhci/usb-ohci), otherwise rebuild the kernel and reboot.

If you don't know which usb module to use for your machine ( usb-uhci or usb-ohci ) then check this page, it contains instructions on how to find out.

NOTES:

  • If you had previously compiled in the patched CDCEther driver, remove it from the kernel, having both drivers compiled will prevent the new driver from working.
  • As mentioned by many people, make sure you've compiled in the correct driver into the kernel in the USB Controllers subsection of the USB configuration.
  • Some people report that they're getting the following message when loading the usbdnet module echo_tx not found it looks like you can safely ignore it since it does not prevent the driver from working.
  • Some people have reported file transfer problem on file larger than 65kB, it appears that is was due to the fact that they where using the uhci module instead of the usb-uhci.
    If you're having this kind of problem and you are using the uhci module, try using usb-uhci instead.
  • I've also received reports of kernel crashes when transferring large files with some motherboards ( at least Gigabyte X71 ) and kernel versions ( 2.4.10 and 2.4.18 ). The solution seems to update to a kernel 2.4.19pre8 or higher.

2) Put the Zaurus on the cradle.
You should see a message like this in /var/log/messages :

hub.c: USB new device connect on bus1/1, assigned device number 38
usb.c: USB device 38 (vend/prod 0x4dd/0x8004) is not claimed by any active driver.
v0.4b sl@lineo.com, tbr@lineo.com
usbdnet.c: v0.4b sl@lineo.com, tbr@lineo.com
usbdnet.c: USB Host to Device Network - for Linux USB Devices using MDLM/CDC
usb.c: registered new driver usbdnet

If you don't see this, try to push the sync button on the craddle, it should help !

now do ifconfig -a
you should see a new ethernet interface ( probably usb0 ), you can now configure it :

ifconfig usb0 192.168.129.1 netmask 255.255.255.255 up
route add -host 192.168.129.201 usb0

then try : ping 192.168.129.201 , if you've got a reply, you've won !

3) If you want to be able to connect to the internet from the Zaurus

You'll need to masquerade the Zaurus's IP from your machine.
Let's say that the ethernet interface that connects you to the internet is ethX and that it's IP is MY_IP, you would need to do the following :

make sure you enable the following options in the kernel : in "Networking options", select :

  • Network packet filtering (replaces ipchains)
  • in "IP: Netfilter Configuration" select at least
    • "IP tables support (required for filtering/masq/NAT)" (as a module if you want)
    • "Connection tracking (required for masq/NAT)" (as a module if you want)
    • "Full NAT" (as a module if you want)
    • "MASQUERADE target support (NEW)" (as a module if you want)

Then recompile your kernel & modules .... and reboot

then do the following :
ifconfig usb0 192.168.129.1 netmask 255.255.255.255 up
route add -host 192.168.129.201 usb0
iptables -t nat -F
iptables -t nat -A POSTROUTING -j SNAT -o ethX --to MY_IP
echo 1 > /proc/sys/net/ipv4/ip_forward

on the Zaurus side :
add a default route pointing to your linux PC :
route add -host 192.168.129.1 usbd0
route delete -net 192.168.129.0/24 usbd0
route add default gw 192.168.129.1

then edit /etc/resolv.conf to add the IP of your DNS:
add a line like this nameserver xxx.xxx.xxx.xxx where xxx.xxx.xxx.xxx is the address of your nameserver.

4) If you're using hotplug, you can automate everything !

In order to have hotplug setup everything when you plug your Zaurus on your PC, you'll need to create a script /etc/hotplug/usb/usbdnet that should look like this ( feel free to adapt it to your needs )

#! /bin/bash
typeset -i num
num=`ifconfig | grep usb0 | wc -l`
if [ $num -eq 0 ] ; then
	ifconfig usb0 192.168.129.1 netmask 255.255.255.255 up
	route add -host 192.168.129.201 usb0
fi
iptables  -t nat -F
iptables  -t nat -A POSTROUTING -j SNAT -o eth0 --to MY_IP
echo 1 > /proc/sys/net/ipv4/ip_forward

This will automatically do the dirty work for you !

have fun !

5) Additionnal notes

  • If you're having problem synchronizing with your Zaurus using the qtopia destkop, read the following:
    With the latest ROMS qtopia has been "hardened" a little bit and now accepts only connections on port 4242 and 4343 ( ftp and sync ports ) from an IP that has been assigned by the Zaurus's dhcp server or that is equal to 192.168.129.1.
    The solution is to use one of the following:
    • Assign 192.168.129.1 to the PC usb interface ( see instructions below ).
    • Use the dhcp server running on the Z to get the IP address of the PC's usb interface by running dhcpd /dev/usb0 on the PC instead of doing the manual IP assignment.

6) If you're using Mandrake 8.2 by David Cafaro

No patch is needed at all. The usbdnet driver is already installed.
The only thing needed to do from the default mandrake install was change two value in the modules.usbmap and add the /etc/sysconfig/network-scripts/ifcfg-usb0 file.

The ifcfg-usb0 file should contain the following:

BOOTPROTO=static
BROADCAST=192.168.129.255
IPADDR=192.168.129.1
NETMASK=255.255.255.0
NETWORK=192.168.129.0
DEVICE=usb0
In the /lib/modules/`uname -r`/modules.usbmap file one line needs to be changed. Look for a line that starts with the following:
usbdnet              0x0193      0x40dd   0x8004    0x0000
or
usbdnet              0x0193      0x04dd   0x8004    0x0000

and change one of them to this:

usbdnet              0x0003      0x04dd   0x8004    0x0000

Only one line in the file needs to be changed as far as I can tell (the other usbdnet lines are for different hardware, maybe?). I did find that after two days my modules.usbmap file reverted back to it's original version. I had to just change the one line again to get things working once more. I don't know if that is just something flaky with my system, or something more. Any ideas are welcome. Enjoy.

7) If you're using Suse 8.0, by Christian Weigand

  • Suse 7.1: the patch for kernel 2.4.16 works fine on the kernel provided with this version of Suse.
  • Suse 8.0: There's now a specific patch for the kernel shipped with Suse 8.0, you can grab it in the Patches directory. Thanks to Detlef Grittner.

First make sure that hotplut is enabled, check the following: /etc/sysconfig/hotplug has to contain:

HOTPLUG_START_NET=yes
Then to get it working with hotplug the only thing needed to do from here is to create the file ifcfg-usb0 in the directory /etc/sysconfig/network with the following input. I just used the ifcfg.template file which can be found there.
# This is a template for a network interface configuration file used with ifup.
# See 'man 8 ifup' for details.
# Additionally to the following variables you can set every variable from the
# interface independent configurations files (config, dhcp, wireless) to
# overwrite the global settings.

# STARTMODE tells ifup when a interface should be set up. Possible values are:
# - onboot: start it at boot time
# - manual: start it only when ifup is called manually
# - hotplug: start it when ifup is called by hotplug or pcmcia
# Do not use 'onboot' for hotpluggable devices. That does not work.
STARTMODE=hotplug

# With BOOTPROTO you can choose between a 'static' configuration with fixed
# IP addresses or 'dhcp'. (bootp does not work on SuSE Linux 8.0)
BOOTPROTO="static"

# If using a static configuration you have to set an IP address and a netmask
# or prefix length. The following examples are equivalent:
# 1) IPADDR=192.168.1.1
#    NETMASK=255.255.255.0
# 2) IPADDR=192.168.1.1
#    PREFIXLEN=24
# 3) IPADDR=192.168.1.1/24
IPADDR=192.168.129.1
NETMASK=255.255.255.
PREFIXLEN=24

# Set the broadcast address of this interface. If you leave it empty a default
# will be used. See DEFAULT_BROADCAST in /etc/sysconfig/network/config.
BROADCAST=192.168.129.255

# If you'd like to set up a point to point connection you may specify the
# remote IP here.
REMOTE_IPADDR=192.168.129.201

# Set a label for the interface. See 'multiple addresses' below.
LABEL=

# Have a look at the iproute2 documentation.
SCOPE=

# Every other option from "ip address add" can be added here.
IP_OPTIONS=

# Multiple addresses (aka aliases)
# There are several ways to assign more than one IP address to a network
# interface. If you ever want to use YaST2 for this you should choose the
# first possibility:
# 1) one IP address per config file:
#    create multiple copies of your master config files and add ':' to
#    the filenames of the copy. Prefer increasing number starting at 1.
# 2) multiple IP addresses per config file:
#    You can extend the variable name 'IPADDR' by any string you like (IPADDR_1,
#    IPADDR-FOO, IPADDRxxx, ...) and use these variables for your IP addresses.
#    If you need some additional parameters for these addresses, then just add
#    the same extension to these variable names.
#    IPADDR_AAA=1.2.3.4
#    NETMASK_AAA=255.0.0.0
#    BROADCAST_AAA=1.2.3.55
#    IPADDR_BBB=10.10.2.3/16
#    LABEL_BBB=BBB
#    an so on ...
#
# You do not need to set a label for any address. But then you should not use
# ifconfig any longer; go and use ip. If you want to use ifconfig then omit the
# label for your main address and set a label for every additional address.
# This is equivalent with using aliases with method 1.
#
# !!! YaST2 is not able to read multiple addresses from one file. Use this only
# if you configure your stuff manually anyway !!!

# Routing:
# If you need special routes for a configuration, then use a file named
# ifroute- where  is the same string as in ifcfg-.
# It has the same syntax like routes except one difference:
# If you omit the interface name (4th field) in the ifroute file it will be
# set to the current interface name when setting up the interface. You need to
# do this with hotpluggable devices, where you do not know which interface name
# they will get at the time when you plug them.
# See man 5 routes.

Now the route to the zaurus should be set automatically every time you plug your zaurus in the cradle. You can check this by typing ifcfg -a. To the usb0 device should be an IP address assigned.

If you need to change the USB driver that you're using, the following tip from Pirmin Kalberermight be helpful:
To use usb-uhci instead of uhci edit /etc/sysconfig/hotplug and change

HOTPLUG_USB_HOSTCONTROLLER_LIST="uhci usb-uhci usb-ohci ehci-hcd"
to

HOTPLUG_USB_HOSTCONTROLLER_LIST="usb-uhci uhci usb-ohci ehci-hcd"

Now enjoy it.

8) If you're using Debian by Fabian Wickborn

For Debian systems you only have to install hotplug (and the appropriate patched kernel, of course).
Then add the following lines to /etc/network/interfaces

iface usb0 inet static
    address 192.168.129.1
    pointopoint 192.168.129.201
    netmask 255.255.255.255
Hotplug should set up your usb0 device everytime you insert the Z in the cradle.

9) Kernel version >=2.4.21

Great news :
Starting with kernel 2.4.21, there is out of the box support for the Zaurus in the kernel.
You don't need to patch the kernel anymore !!
In the linux kernel configuration just make sure you select the following:
In the USB support section, in the USB Network adaptors subsection, select USB-to-USB Networking cables, Linux PDAs and recompile the modules ( make modules modules_install ).

From there, the zaurus should be recognized and configured out of the box. If you're using hotplug, you just need to change the instructions provided above by replacing usbdnet by usbnet ( i.e replace /etc/hotplug/usb/usbdnet by /etc/hotplug/usb/usbnet ).
Note: You might have to add cdcether and acm to the /etc/hotplug/blacklist list in order to get the usbnet module to be loaded.
It depends on whether you're using distribution precompiled kernel which includes all modules by default or if you're using a home compiled kernel in which you've not selected this modules.