world leader in high performance signal processing
Trace: » nfs

The Network File System (NFS)

NFS stands for Network File System. It allows you to mount remote directories and access the contents as if the file system was mounted locally.

For more specific information on NFS you may want to look at the NFS website on SourceForge. If you do not have a Linux or Unix machine available to act as the NFS server, you can do it on a Windows machine with Microsoft's Services For Unix (SFU). If you're running OS X, then check out the OS-X hints page.

Server Setup

Setting up a server is outside the scope of this document, as it is very specific to the distribution. If you are having problems setting up a server, or getting errors that look like:

RPC:unable to receive,errno=no route to host
nfsmount failed: Bad file descriptor
Mounting 192.168.0.5:/home/share on /mnt failed: Invalid argument

It is most likely due to the host or NFS server not being set up properly. To solve these types of issues, check out:

Kernel Settings

In your kernel configuration menu, make sure you have these settings enabled:

File systems  --->
  Network File Systems  --->
    [*] NFS client support
    [*]   NFS client support for NFS version 3

If you wish to use NFS as your root filesystem, you will also need these settings:

Networking  --->
  Networking options  --->
    [*] TCP/IP networking
    [*]   IP: kernel level autoconfiguration
File systems  --->
  Network File Systems  --->
    [*] Root file system on NFS

Even if you do not boot from NFS, these settings are safe to have enabled.

uClinux-dist Settings

In your vendor/user configuration menu, make sure you have these settings enabled:

Network Applications  --->
  [*] portmap
BusyBox  --->
  Linux System Utilities  --->
    [*] mount
    [*]   Support mounting NFS file systems

Runtime Usage

Once you've booted the new system and set up the network, we can get started.

Portmap

First you need to launch portmap. This program manages the port number mappings of RPC programs. Simply run on the board:

# portmap &

This step is not strictly necessary as you can add the nolock to the -o option on the mount command line. If you're not familiar with this, just run portmap & and be done.

Mounting

Now you can actually mount an NFS directory. For example:

root:~> mount -o nfsvers=3,tcp,rsize=1024,wsize=1024 –t nfs 192.168.0.1:/share/bfin /mnt

This will mount the share /share/bfin on the remote server 192.168.0.1 on the local directory /mnt. The additional options given to -o here force NFS version 3 to be used over TCP, and set the read and write buffer size to 1k (1024 bytes). While NFS version 2 and UDP should work, NFS version 3 and TCP tend to be much more robust (which is pretty logical).

For other fun mount options (such as to to control locking/read buffer size/write buffer size/etc…), please consult the man pages on your development system. The nfs(5) and mount(8) pages should document everything.

Make sure that your NFS server has write capabilities so that you can write back to the server.

You may get a warning that says mount version older than kernel. Just ignore this as the mount should still work fine.

Stability of the NFS mount may suffer by not including the limiting of input and output buffers to 1KByte. This is achieved by adding the options rsize=1024 and wsize=1024 to the mount command line.

NFS Root

Once you've enabled the appropriate kernel settings, and you've set up the NFS server for root and writing access, you just need to add the appropriate options to your kernel command line.

The default U-Boot comes with some helper scripts called nfsboot and nfsargs:

bfin> printenv nfsboot nfsargs
nfsboot=tftp $(loadaddr) vmImage;run nfsargs;run addip;bootm
nfsargs=set bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath),tcp,nfsvers=3

As you can see, the key parts are setting your root= to /dev/nfs and setting nfsroot= accordingly. If you find yourself not seeing console output through the serial line, you should add console=ttyBF0,115200 to nfsargs. The file linux-2.6.x/Documentation/filesystems/nfs has all the gory details.

The differences to note when booting:

  • boot the vmImage instead of the uImage as the latter does not have a rootfs attached to it; moreover this speeds up test iteration cycles when the make process is appropriately cut down.
  • make sure your nfsroot directory has a /dev directory, otherwise the device tree isn't set up properly.

Here is an example good NFS root boot:

U-Boot 1.1.6-ga36a5315-svn1144 (ADI-2008R2-pre) (Feb  4 2008 - 23:49:11)

CPU:   ADSP bf537-0.2 (Detected Rev: 0.2)
Board: ADI BF537 stamp board
      Support: http://blackfin.uclinux.org/
Clock: VCO: 500 MHz, Core: 500 MHz, System: 100 MHz
RAM:   64 MB
Flash:  4 MB
In:    serial
Out:   serial
Err:   serial
Net:   Blackfin EMAC
MAC:   00:E0:22:FE:44:EC
I2C:   ready
Hit any key to stop autoboot:  0
bfin> print

[only relevant vars are shown]
ipaddr=192.168.0.15
serverip=192.168.0.17
gatewayip=192.168.0.1
netmask=255.255.255.0
addip=set bootargs $(bootargs) ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname):eth0:off
nfsboot=tftp $(loadaddr) vmImage;run nfsargs;run addip;bootm
rootpath=/usr/local/src/blackfin/svn/uclinux-dist/trunk/romfs
nfsargs=set bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath),tcp,nfsvers=3,rsize=1024,wsize=1024

bfin> run nfsboot
Using Blackfin EMAC device
TFTP from server 192.168.0.17; our IP address is 192.168.0.15
Filename 'vmImage'.
Load address: 0x1000000
Loading: #################################################################
        #################################################################
        #############################################################
done
Bytes transferred = 973197 (ed98d hex)
## Booting image at 01000000 ...
  Image Name:   Linux-2.6.24-ADI-2008R2-pre-svn4
  Created:      2008-02-12   2:21:31 UTC
  Image Type:   Blackfin Linux Kernel Image (gzip compressed)
  Data Size:    973133 Bytes = 950.3 kB
  Load Address: 00001000
  Entry Point:  001a8000
  Verifying Checksum ... OK
  Uncompressing Kernel Image ... OK
Starting Kernel at = 1a8000
Linux version 2.6.24-ADI-2008R2-pre-svn4245 (vapier@G5) (gcc version
4.1.2 (ADI svn)) #18 Mon Feb 11 21:21:27 EST 2008
Warning: limiting memory to 56MB due to hardware anomaly 05000263
Board Memory: 64MB
Kernel Managed Memory: 64MB
Memory map:
 text      = 0x00001000-0x00128260
 rodata    = 0x001283a0-0x00180920
 bss       = 0x00180920-0x00191f58
 data      = 0x00191f58-0x001a8000
   stack   = 0x001a6000-0x001a8000
 init      = 0x001a8000-0x001c7000
 available = 0x001c7000-0x037ff000
 DMA Zone  = 0x03f00000-0x04000000
Hardware Trace Active and Enabled
Reset caused by Software reset
Blackfin support (C) 2004-2008 Analog Devices, Inc.
Compiled for ADSP-BF537 Rev 0.2
Blackfin Linux support by http://blackfin.uclinux.org/
Processor Speed: 500 MHz core clock and 100 MHz System Clock
Instruction Cache Enabled
Data Cache Enabled (write-through)
Built 1 zonelists in Zone order, mobility grouping off.  Total pages: 14224
Kernel command line: root=/dev/nfs rw nfsroot=192.168.0.17:/usr/local/src/blackfin/svn/uclinux-dist/trunk/romfs,tcp,nfsvers=3 ip=192.168.0.15:192.168.0.17:192.168.0.1:255.255.255.0:1:eth0:off
Configuring Blackfin Priority Driven Interrupts
PID hash table entries: 256 (order: 8, 1024 bytes)
console [ttyBF0] enabled
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory available: 54940k/65536k RAM, (124k init code, 1180k kernel
code, 512k data, 1024k dma, 7756k reserved)
Blackfin Scratchpad data SRAM: 4 KB
Blackfin Data A SRAM: 16 KB (15 KB free)
Blackfin Data B SRAM: 16 KB (16 KB free)
Blackfin Instruction SRAM: 48 KB (41 KB free)
Security Framework initialized
Mount-cache hash table entries: 512
net_namespace: 64 bytes
NET: Registered protocol family 16
Blackfin GPIO Controller
Blackfin DMA Controller
stamp_init(): registering device resources
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 2048 (order: 2, 16384 bytes)
TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
TCP: Hash tables configured (established 2048 bind 2048)
TCP reno registered
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler cfq registered
Dynamic Power Management Controller Driver v0.1: major=10, minor = 254
Serial: Blackfin serial driver
bfin-uart.1: ttyBF0 at MMIO 0xffc00400 (irq = 18) is a BFIN-UART
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
bfin_mac_mdio: probed
bfin_mac: attached PHY driver [SMSC LAN83C185] (mii_bus:phy_addr=0:01,
irq=-1, mdc_clk=2500000Hz(mdc_div=19)@sclk=100MHz)
bfin_mac: Version 1.1, Blackfin BF53[67] BF527 on-chip Ethernet MAC driver
bfin-spi bfin-spi.0: Blackfin BF5xx on-chip SPI Controller Driver,
Version 1.0, regs_base@ffc00500, dma channel@7
bfin-wdt: initialized: timeout=20 sec (nowayout=0)
TCP cubic registered
NET: Registered protocol family 1
NET: Registered protocol family 17
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
IP-Config: Complete:
     device=eth0, addr=192.168.0.15, mask=255.255.255.0, gw=192.168.0.1,
    host=1, domain=, nis-domain=(none),
    bootserver=192.168.0.17, rootserver=192.168.0.17, rootpath=
Looking up port of RPC 100003/3 on 192.168.0.17
PHY: 0:01 - Link is Up - 100/Full
Looking up port of RPC 100005/3 on 192.168.0.17
VFS: Mounted root (nfs filesystem).
Freeing unused kernel memory: 124k freed
dma_alloc_init: dma_page @ 0x001c4000 - 256 pages at 0x03f00000
                          _____________________________________
       a8888b.           / Welcome to the uClinux distribution \
      d888888b.         /       _     _                         \
      8P"YP"Y88        /       | |   |_|            __  __ (TM)  |
      8|o||o|88  _____/        | |    _ ____  _   _ \ \/ /       |
      8'    .88       \        | |   | |  _ \| | | | \  /        |
      8`._.' Y8.       \       | |__ | | | | | |_| | /  \        |
     d/      `8b.       \      \____||_|_| |_|\____|/_/\_\       |
    dP   .    Y8b.       \   For embedded processors including   |
   d8:'  "  `::88b        \    the Analog Devices Blackfin      /
  d8"         'Y88b        \___________________________________/
 :8P    '      :888
  8a.   :     _a88P         For further information, check out:
 ._/"Yaa_:   .| 88P|            - http://blackfin.uclinux.org/
 \    YP"    `| 8P  `.          - http://docs.blackfin.uclinux.org/
 /     \.___.d|    .'           - http://www.uclinux.org/
 `--..__)8888P`._.'  jgs/a:f    - http://www.analog.com/blackfin

Have a lot of fun...


BusyBox v1.9.0 (2008-02-11 13:43:09 EST) built-in shell (msh)
Enter 'help' for a list of built-in commands.

root:/> mount
rootfs on / type rootfs (rw)
/dev/root on / type nfs (rw,vers=3,rsize=1024,wsize=1024,hard,nointr,nolock,proto=tcp,timeo=600,retrans=2,sec=sys,addr=192.168.0.17)
proc on /proc type proc (rw)
ramfs on /var type ramfs (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw)
debugfs on /sys/kernel/debug type debugfs (rw)
securityfs on /sys/kernel/security type securityfs (rw)
root:/>

Troubleshooting

You may get an error during the mount portion. If you see a line like this:

Root-NFS: Server returned error -13 while mounting /tftpboot/bf548-ezkit

Then look up the value listed there (13 in this case). It is a standard errno value. So in your kernel sources, do this:

$ grep -h '\<13\>' linux-2.6.x/include/asm-generic/*errno*
#define EACCES          13      /* Permission denied */

Permission denied from the server might mean one of two things:

  • your kernel command line is incorrect and the board is attempting to mount an invalid path which the server then rejects
  • your server is misconfigured and isn't exposing the mounts correctly, so go back up and review the NFS documentation