Please note that User Registration has been temporarily disabled due to a recent increase in automated registrations. If anyone needs an account, please request one here: RequestAccount. Thanks for your patience!--Wmat (talk)
Please email User:Wmat if you experience any issues with the Request Account form.

Mount BeagleBoard Root Filesystem over NFS via USB

From eLinux.org
Jump to: navigation, search

This page explains how to bridge the usb0 device to eth0 on your Linux host, enabling your Linux host to act as a hub for your BeagleBoard and connecting it to the outside world. As an additional reference, the following article is good at explaining how to create a typical Ethernet bridge on a Linux machine with two Ethernet cards:

Linux Journal: Kernel Korner - Linux as an Ethernet Bridge

Before starting, make sure you have the "bridge-utils" package installed on your Linux host. This gives you the "brctl" command, which you need for creating and using an Ethernet bridge.


Step 1: Create an Ethernet Bridge from usb0 to eth0 on your Linux Host

The main difference between the scenario in the Linux Journal article mentioned above and the BeagleBoard is that we're creating a bridge from usb0 to eth0 instead of from eth1 to eth0. Also, we have to deal with the fact that "usb0" doesn't exist as a device on our Linux host except when the USB Gadget support is running on the connected Beagleboard, which isn't the case when we're first booting the Linux host.

My Linux host is running Fedora Core 10. I'm sure some of the following network configuration steps are specific to Fedora, but they can probably be easily adapted to other Linux distributions. On Fedora, I edited the network scripts "/etc/sysconfig/network-scripts/ifcfg-eth0" and "/etc/sysconfig/network-scripts/ifcfg-usb0" by hand to make sure those interfaces had no IP or gateway settings, and that they were not controlled by the Fedora network manager by setting NM_CONTROLLED=no.

Contents of /etc/sysconfig/network-scripts/ifcfg-eth0:

DEVICE=eth0
ONBOOT=no
BOOTPROTO=none
TYPE=Ethernet
USERCTL=no
PEERDNS=yes
IPV6INIT=no
NM_CONTROLLED=no

Contents of /etc/sysconfig/network-scripts/ifcfg-usb0:

DEVICE=usb0
ONBOOT=no
BOOTPROTO=none
TYPE=Ethernet
USERCTL=no
IPV6INIT=no
NM_CONTROLLED=no
PEERDNS=yes

Next, I created a new script "/etc/sysconfig/network-scripts/ifcfg-br0" that is going to be the "bridge" interface that connects both usb0 and eth0 to the outside world. This script looks a lot like what "ifcfg-eth0" used to look like.


Contents of /etc/sysconfig/network-scripts/ifcfg-br0:

# Ethernet Bridge
DEVICE=br0
ONBOOT=no
SEARCH="dmlab"                 # Replace with your search domains
BOOTPROTO=none
NETMASK=255.255.255.0          # Replace with your subnet's netmask
IPADDR=192.168.198.1           # Replace with your Linux host's IP address
USERCTL=no
PEERDNS=yes
IPV6INIT=no
GATEWAY=192.168.198.254        # Replace with your subnet's gateway
TYPE=Ethernet
DNS1=192.168.198.1
DOMAIN='dmlab'                 # Replace with your Linux host's domain(s)
NM_CONTROLLED=no

Next, I created following init script and placed it in /etc/init.d/br0.

Contents of /etc/init.d/br0:

#!/bin/bash

# Source function library.
. /etc/rc.d/init.d/functions

RETVAL=0

# Check if all what named needs running
start()
{
   /usr/sbin/brctl addbr br0
   /usr/sbin/brctl addif br0 eth0
   /sbin/ifup eth0
   /sbin/ifup br0
   return 0;
}

stop() {
   /sbin/ifdown br0
   /sbin/ifdown eth0
   /usr/sbin/brctl delbr br0
}


restart() {
	stop
	start
}	

# See how we were called.
case "$1" in
	start)
		start
		;;
	stop)
		stop
		;;
	restart)
		restart
		;;
	*)
        	echo $"Usage: $0 {start|stop|restart}"
		exit 3
esac

exit $RETVAL


I set the br0 init script to run during bootup by making the following symbolic link:

ln -s /etc/init.d/br0 /etc/rc5.d/S91br0

My system typically runs at runlevel 5 (hence rc5.d), and "S91" on my system runs after the networking scripts, but before critical services like dns, named, dhcp, samba, etc, which need the interface to be up when starting.

The br0 script manually brings up eth0 and br0, which is why it is important that these interfaces are not controlled by Fedora's network manager.

After re-booting the Linux host (without a BeagleBoard attached), the result of "ifconfig" should list "br0", "eth0", and "lo", and if you execute "sudo brctl show" it should list eth0 as being a member of the bridge.

$ ifconfig

br0       Link encap:Ethernet  HWaddr xx:xx:xx:xx:xx:xx  
          inet addr:192.168.198.1  Bcast:192.168.198.255  Mask:255.255.255.0
          inet6 addr: fe80::21a:a0ff:feec:79f1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3875507 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3351392 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:2798652354 (2.6 GiB)  TX bytes:977920512 (932.6 MiB)

eth0      Link encap:Ethernet  HWaddr xx:xx:xx:xx:xx:xx  
          inet6 addr: fe80::21a:a0ff:feec:79f1/64 Scope:Link
          UP BROADCAST RUNNING PROMISC MULTICAST  MTU:1500  Metric:1
          RX packets:2015574 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3411988 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1780819388 (1.6 GiB)  TX bytes:972140276 (927.1 MiB)
          Interrupt:16 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:236666 errors:0 dropped:0 overruns:0 frame:0
          TX packets:236666 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:317726283 (303.0 MiB)  TX bytes:317726283 (303.0 MiB)

$ sudo brctl show

bridge name bridge id STP enabled interfaces br0 8000.001aa0ec79f1 no eth0

You should be able to access the external network the same as before on your Linux host at this point.

Step 2: Booting the BeagleBoard

The next step is to boot the BeagleBoard with kernel parameters that tell it to mount its root file system over NFS. Here are the U-Boot settings I used to boot the kernel from an SD card, then boot the rootfs over NFS:

setenv bootargs 'console=ttyS2,115200n8 noinitrd rw ip=192.168.198.24::255.255.255.0 root=/dev/nfs
nfsroot=192.168.198.1:/opt/dmsw/OE_BEAGLE_rootfs,nolock,rsize=1024,wsize=1024,rootdelay=2'
setenv bootcmd 'mmcinit;fatload mmc 0 80300000 uImage;bootm 80300000'

In the above parameters, replace the following with settings for your network:

Replace This With This
ip=192.168.198.24::255.255.255.0 ip=<BeagleBoard IP Address>::<your subnet mask>
nfsroot=192.168.198.1:/opt/dmsw/OE_BEAGLE_rootfs nfsroot=<IP address of your NFS server>:<path to root filesystem on NFS server>

While the BeagleBoard kernel is booting, the usb0 device will show up on the Linux host. Run "ifconfig" a few times, and when "usb0" is listed, run the following command:

$ sudo brctl addif br0 usb0

This will add "usb0" to the Ethernet bridge, and the Linux host will now act as a hub for the Beagleboard. The Beagleboard will now continue to boot, but the weird thing is I didn't see any of the kernel boot messages scroll by while it's starting up. However, when it's done the "Angstrom" prompt comes up on the serial normally.

If you execute "sudo brctl show" after the BeagleBoard is done booting, it should now should both eth0 and usb0 being on the bridge:

$ sudo brctl show

bridge name     bridge id               STP enabled     interfaces
br0             8000.001aa0ec79f1       no              eth0
                                                        usb0

Step 3: Accessing the Outside World from the BeagleBoard

You might want to make sure that any firewall software like iptables is disabled on the Linux host, or at least make sure the firewall settings allow the Linux host to act as a hub for your BeagleBoard. Otherwise, the BeagleBoard will not be able to see the outside world.

On the BeagleBoard, modify "/etc/network/interfaces", and configure the settings for "usb0".

Contents of BeagleBoard's /etc/network/interfaces:

iface usb0 inet static
        address 192.168.198.24   # Replace with BeagleBoard's IP Address
        netmask 255.255.255.0    # Replace with your subnet mask
        network 192.168.198.0    # Replace with your network address
        gateway 192.168.198.254  # Replace with your subnet gateway

Also, edit the /etc/resolve.conf on the BeagleBoard to point to your DNS server. Here are my settings:

Contents of BeagleBoard's /etc/resolve.conf:

search dmlab                     # Replace with your domain search path                     
nameserver 192.168.198.1         # Replace with your DNS server

Note that my linux host (192.168.198.1) is running a DNS server. If yours isn't, don't use your Linux host IP here -- set this to the DNS server that your Linux host is using.

Finally, bring up the usb0 interface on the BeagleBoard:

$ ifup usb0

You should now be up and connected as if your beagle board was on the network at the same level as the linux host.

$ ping some.machine.com

PING some.machine.com (192.94.93.21): 56 data bytes                               
64 bytes from 192.94.93.21: seq=0 ttl=247 time=18.005 ms                        
64 bytes from 192.94.93.21: seq=1 ttl=247 time=10.254 ms                        
...

Automatically add usb0 to br0

Create /etc/udev/rules.d/52-add-net-usb-to-br.rules which adds usb0 to the bridge br0.

SUBSYSTEM=="usb", INTERFACE=="usb*", RUN+="/usr/sbin/brctl addif br0 usb0"

Tested under Ubuntu Linux 9.04 host. Unplug the USB cable, run sudo brctl show, then plug the cable and run sudo brctl show again to verify it was added.

Future Considerations

  • Make the udev script aware of the actual interface name (usbX).