NSLU2-Linux
view · edit · print · history

I have managed to enable the device side USB port, using some spare bits from a dead Epson printer and some old power supplies. any EE's in the crowd will cringe when they see this, as I have made no attempt to impedance match any of the circuit, and violate the USB protocol by not having the pull-up under software control. that said, this does work just fine, and I have used the NSLU2 as a mass-storage device (it pretends to be a flash drive) back to my Linux box.

Background

USB has 4 wires, 5V, D-, D+, and ground. the D (data) lines are a differential pair, like 10Base-T ethernet uses, but unlike ethernet which has separate TX and RX pairs (enabling full duplex), USB has one pair. The host (PC) initiates all transactions on this pair to avoid collisions. The standard type-A ports on the NSLU2 are host side ports. we are adding a device side port, which will enable the NSLU2 to show up as an external hardrive or even a networking or serial device, when plugged into a PC (or other NSLU2!)

USB 1.1 spec says that any device running at full speed (12Mb/s) should have a pullup resistor between the D+ line and a source of 3.0V to 3.6V. This source must be derived from the 5V line in the USB cable, and not from the power supply of the device itself. we use a simple divider network.

You will need

  • Three 1/8th watt resistors (15K, 1.5K, and 1K)
  • Two lengths of fine (~20 gauge or less) multi-strand wire, 5 inches each.
  • Female USB type-B connector (the square one, surface mount is fine)

Installation

  1. Install port

    I scuffed the side of the new USB port and the side of the ethernet port with sandpaper, then used superglue to attach the port, right over the crystal can Y1. I even used a bit of glue on top of that crystal too. make the face of the port flush with the ethernet port. Let it set. Cut a square out of the back plastic housing, removing all of the word ethernet.
  2. Ground port

    Then use a bit of solder to make sure the shield of the USB port is grounded to the ethernet port's shield. use flux. If you cant bridge the gap cause you got crazy with the superglue, add a bit of wire.
  3. Ground pin 4

    Bend the back of pin 4 so that it touches the shield, and solder it. Mine had a convenient tab for surface mounting, that I rolled inwards to reach the pin.
  4. Add resistors

    Solder 1K resistor to pin 1, 15K resistor to pin 4 or shield ground, and 1.5K resistor to pin 3. All the resistors should stick out in the same direction. Solder the other end of all three of them together. this little 'tripod' will provide ~3.5 volts to the D+ pin (#3) whenever the cable is connected to a powered-on host, even if the NSLU2 is OFF.
  5. Remove SMD resistors

    We have to get R130 and 131 off the back of the board. easiest way is with a forked-tip soldering iron. I don't have one :) The next easiest way involves desoldering wick. I ran out :) So, get yourself a bit of thin stranded wire, dip the tip in flux, put it on one end of the resistor, and press down on wire with soldering iron. you should see solder 'wick' up the wire. Use fresh wire at all four joints. be careful to pull the wire away while the solder is still hot, not after it has cooled. Now, while the resistor is still hot, put your iron down against one end of the resistor, wait a second, and push. it should slide off.
  6. Add wire

    We are going to connect pin 2 to the left side of where R130 was. do not bridge over to the right side accidentally. It won't work, and it might burn out the driver in the CPU. connect pin 3 (same place the resistor connects) to left side of R131. Don't bridge it either. Keep those wires as short as possible, and the same length (± 1/4 inch).
  7. Software

    I used the crosstool instructions on the wiki to build a compiler. then I used the newest testing release of uCLinux-dist to build a 2.4 kernel and ramdisk. I had to modify the file drivers/USB/gadget/pxa2xx_udc.c before compiling, because that kernel (2.4.27) did not know the IXP420.

    Down around line 2420:

    default:
            out_dma = 0;
            printk(KERN_ERR "%s: unrecognized processor: %08x\n",
                    driver_name, chiprev);
            return -ENODEV;

    becomes:

    default:
            out_dma = 0;
            printk(KERN_ERR "%s: unrecognized processor: %08x\n",
                    driver_name, chiprev);
            break;

    Make sure to enable the USB gadget stuff, especially the Intel pxa2xx_udc driver.
  8. Load

    Put the kernel and ramdisk on your TFTP server and load them from RedBoot. you should see a message during bootup 'unrecognized processor: 690541f1' don't have the USB cable plugged in during this.
  9. Make file

    On the NSLU2 type 'dd bs=1k if=/dev/zero of=/foo.fs count=512' then 'insmod /lib/modules/2.4.27-uc0/kernel/drivers/USB/gadget/g_file_storage.o file=/foo.fs' (all on one line). this makes a 512KB file with nothing in it, and tells the gadget driver to make that file available via the mass storage interface.
  10. Connect

    Plug in the new port into your PC. it should show up as a SCSI device on linux, though it will have no partition table or FS. you can add them now from the PC side. 'fdisk /dev/sda', 'mkdosfs /dev/sda1', 'mount /dev/sda1 /mnt/flash', etc.

    You can unmount/disconnect cable, then reconnect cable/remount, and the files will still be there. if you have an attached disk, you can make foo.fs on it instead, or even use the disk partition directly, I suppose.

Known bugs

The pullup on D+ should not be connected if the device is not ready to answer enumeration setup packets. to do this right, we have to connect a GPIO pin to control a flipflop or transistor between D+ and the resistor, and have the GPIO pin go off after the gadget driver is loaded. we are out of such pins, so you have to remember to re-plug the NSLU2 after it has booted.

enjoy. allan

Please note that Device Side USB is not currently supported in any 2.6 kernel on the NSLU2 up to and including 2.6.18. There is a possibility that support will be included in a later kernel. However, due to the lack of a spare GPIO pin, I don't think that this will ever be anything other than a clever hack on the NSLU2. Sorry, blaster8

:could you use an I2C? chip of some sort to get an io line? -- plugwash

@plugwash - I'd love it if we could since I'm working on a project that needs the device side USB. You can do all of Allan's instructions, but you'll have to use uClinux because, as blaster8 said...there's no support for the PXA2xx? USB gadget drivers on 2.6.x kernels...believe me...I'VE TRIED! You will need to download and compile uClinux with the 2.4.x kernel (make sure to select this when running xconfig, or you will get 2.6. I had this working once but lost my source files and had to rebuild...it isn't working for me right now. -- NeoMatrixJR?


Some information for anyone wanting to try this Gadget on a 2.6.xx kernel:

Using the OpenWRT? Kamikazi and a couple of small tweaks to the source It works great with this 2.6.21 kernel Even Windows can see the OpenWRT? config web page over usb. I would recommend using the OpenWRT? distribution because it is so small and lean and easy to administer.

The .ko pre-compiled files in the ???download section??? will work for OpenWRT? kamikazi so skip the instructions below unless you want to build from source.

Install OpenWRT? source running the scripts to get a full source code and a working cross-compiler. Once it's finished need to apply two tiny patches to two files

 ./kamikaze_7.09/build_armeb/linux-2.6-ixp4xx/linux-2.6.21.6/include/asm-arm/arch-ixp4xx/irqs.h

and

  ./kamikaze_7.09/build_armeb/linux-2.6-ixp4xx/linux-2.6.21.6/drivers/usb/gadget/pxa2xx_udc.c

(see download section for already patched files)

Edit ./kamikaze_7.09/build_armeb/linux-2.6-ixp4xx/linux-2.6.21.6/.config file to allow usb gadget system and pxa2xx_udc system (see example .config). Then recompile the kernel modules (Substitute the correct path where it got installed for ...???? below)

>export PATH=$PATH:...????/kamikaze_7.09/staging_dir_armeb/bin/

>cd ...???/kamikaze_7.09/build_armeb/linux-2.6-ixp4xx/linux-2.6.21.6/drivers/usb/gadget

>make -C ...???/kamikaze_7.09/build_armeb/linux-2.6-ixp4xx/linux-2.6.21.6 CROSS_COMPILE="armeb-linux-uclibc-" ARCH="arm" CONFIG_SHELL="/bin/bash" CC="armeb-linux-uclibc-gcc"

(The above is a single command line)

Sometimes the kernel build system doesn't detect changes to the .config file so you might have to "touch" some of the source files to get a recompile.

If all goes well, there should be

  • pxa2xx_udc.ko
  • g_ether.ko
  • g_file_storage.ko
  • gadgetfs.ko
  • g_serial.ko

appear in the gadget working directory these can be copied over to the NSLU2 using ssh.

Installation

Slug

then on the slug, run

>insmod pxa2xx_udc.ko

>insmod insmod g_ether.ko host_addr=00:dc:c8:f7:75:05 dev_addr=00:dd:dc:eb:6d:f1

>ifconfig usb0 192.168.5.244 up

should now have something on usb0 to see when run >ifconfig

Windows

On a Windows machine (or a Windows virtual machine under Virtualbox also works) Need a linux.inf from

	/usr/src/linux-2.6.23.1/Documentation/usb/linux.inf
	( need to convert to  dos format file  e.g. I ran
	  >perl -p -e 's/\n/\r\n/' < /usr/src/linux-2.6.23.1/Documentation/usb/linux.inf > linux.inf )

Plug in the usb device, windows should recognise a new item and start asking questions about the driver. Refuse all help from windows to install the driver and point to the directory where the linux.inf file lives when offered the "have a disk" option. See http://docwiki.gumstix.org/index.php/Windows_XP_usbnet

Then, need to setup the network device on Windows. [Start][Connect To->][show all connections] then on Local Area Connection 2 (or whatever it's called, look for Linux usb ethernet / RNDIS... as a name (right-click, then select Properties) On the dialog, select [internet protocol (TCP/IP)] select Properties. then set

	IP address      192.168.5.245
	Subnet mask	255.255.255.0
	Default gateway	192.168.5.1		

Now it is possible to ping the NSLU2 running OpenWRT? at 192.168.5.244 (see previous setup instructions for the linux machine). Even Internet explorer will see it if you put http://192.168.5.244(approve sites) as the web address.

On the hardware, I cut corners a little - just used a single 2.2K resistor between (1) and (3) to pull-up D+. Electrically this small current above 3.5V won't hurt the processor at all. Another tip is looking for R130 and R131 on my Slug were hidden under a sticker.

Hope it works for you too.

???I have some patches, screenshots and photos - where do I upload them to? A I will host those images so you may link to them from here markosjal AT gmai1

This is Very interesting , and much like I have been looking for. Time to retire the old NAS if this will emulate a USB disk and give me simultaneous access as a USB disk and a Network connection at the same time. In the beginning of this page however, it talks about this hack producing a pseudo USB diak from theHDDs connected to the SLUG2?, however near the end in the windows section , it refers to configuring the driver as a network connection. I believe this needs some clarification. Also in need of some clarification is the values of the resistors in relation to USB 1.1 vs USB 2.0. In my case I need to connect this to a USB 1.1 host and ensure that it is seen as a generic mass storage device. I could then use this port for access from my DVD player while accessing the same drives over the LAN. It is perhaps the best solution I have seen for this need!

I am making an assumption here , but If the NSLU2 with hacked firmware will connect to a SMB share will that SMB share also be available on the device side USB port presented as a directory on the pseudo USB disk via device side port?

view · edit · print · history · Last edited by Kram.
Based on work by markosjal, jimwilliams, NeoMatrixJR, plugwash, blaster8, tman, and kitno455.
Originally by tman.
Page last modified on June 22, 2009, at 12:03 AM