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.
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:
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.
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
Once you've booted the new system and set up the network, we can get started.
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.
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.
rsize=1024
and wsize=1024
to the mount command line.
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:
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:/>
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: