"... and no one shall work for money, and no one shall work for fame; But each for the joy of the working, and each, in his separate star, shall draw the thing as he sees it, for the god of things as they are"



Installing an NFS Client on a Beaglebone Black


This page describes how to configure the Beaglebone Black as an NFS Client and a remote Linux PC as an NFS Server so that the contents of a directory on the remote Linux box are visible on the Beaglebone Black. This page is part of a series of web pages which describe how to install C# and Mono on the Beaglebone Black and also how to configure a useful remote compilation and debugging toolchain for it.

The previous page in this series described the installation and configuration of MonoDevelop on a remote Ubuntu Linux 14.1.4 PC. This PC, known as the Development PC, will be used to create C# projects and remotely compile them to executable form. The primary purpose of mapping a directory on the Development PC into the Beaglebone Black is to ensure that any executable code created remotely is instantly and automatically available to run on the Beaglebone Black without any user interaction. In short, a pleasant working environment with remote compilation and execution is achieved by creating an executable on the Development PC using a nice IDE and having NFS automatically move that file over to a mapped directory on the Beaglebone Black where it can be run.

The Development PC needs to be able to provide the files in a directory to the Beaglebone Black. This means the Development PC needs to act as an NFS server and the Beaglebone Black needs to be configured as an NFS Client. In general I followed the instructions on these two pages: https://help.ubuntu.com/community/SettingUpNFSHowTo and http://askubuntu.com/questions/8534/share-files-and-printer-between-two-ubuntu-boxes/8573#8573. The specific steps taken are outlined below.

Setting up the Development PC as an NFS Server

Setting up on the Ubuntu 14.1.4 host (hereinafter referred to as the "Development PC") as an NFS server requires you to be the root user. Rather than prefacing every command by sudo you may wish to just become the root user by issuing the sudo -s command once before starting.

In the examples below, the user on the Development PC is dtree and its home directory is /home/dtree. All projects for the Beaglebone Black created in MonoDevelop are located below the /home/dtree/Beagle/CSharpCode subdirectory. The actual executables generated by MonoDevelop will be much lower in that tree, for example the executable of the HelloWorldTest project is in the location: /home/dtree/Beagle/CSharpCode/HelloWorldTest/bin/Debug/HelloWorldTest.exe.

I have lots of projects and rather than map the bin/Debug directory of each project individually over to the Beaglebone Black I chose to create every project below the CSharpCode directory and then just map the entire directory over to the Beaglebone Black. I then use a small shell script on the Beaglebone Black (discussed later) which I can invoke to run appropriate executable for each project in its location in the CSharpCode tree.

First (as root on the Development PC) we install the required packages...

apt-get install nfs-kernel-server 

Create an export filesystem:

mkdir -p /export/BBBNFS

Make sure the permissions are 777

chmod 777 /export/BBBNFS

Mount the directory we wish to map into the export filesystem

mount --bind /home/dtree/Beagle/CSharpCode /export/BBBNFS

Edit the line in the /etc/default/nfs-kernel-server file to say


Confirm the /etc/idmapd.conf file has the lines

Nobody-User = nobody
Nobody-Group = nogroup

Add the line below to /etc/exports file ( is IP address of the armhf Beaglebone Black NFS client)


Restart the nfs server

/etc/init.d/nfs-kernel-server restart

Set portmap lockdown and deny all in /etc/hosts.deny by adding the line below to that file

rpcbind mountd nfsd statd lockd rquotad : ALL 

Allow a specific IP in /etc/hosts.allow by adding the line below to that file

rpcbind mountd nfsd statd lockd rquotad : 

Restart the nfs server

service nfs-kernel-server restart

edit /etc/fstab so it mounts our filesystem automatically by adding the line

/home/dtree/Beagle/CSharpCode   /export/BBBNFS    none    bind  0  0

At this point the Development PC is prepared to serve the contents of the /home/dtree/Beagle/CSharpCode subdirectory to an NFS client at IP address The next task is to set up an NFS Client on our Beaglebone Black

Setting up the Beaglebone Black as an NFS Client

The user on the Beaglebone Black is debian and its home directory is /home/debian. We will map the exported CSharpCode directory into our local filesystem in the /home/debian/CSharpCode directory. Once mapped, we will have local access on the Beaglebone Black to all files in the Development PC's /home/dtree/Beagle/CSharpCode subdirectory. This mapped file system will be fully read-write by both parties. Any changes, by either the Development PC or the Beaglebone Black, to the files in this tree will be immediately reflected to the other party by NFS.

Install the nfs client (as root on the Beaglebone Black)

apt-get install nfs-common 

Make a mount point for the nfs drive offered from the Development PC

mkdir /home/debian/CSharpCode 

Mount the exported NFS drive. The IP address is the address of the Linux Development PC (also configured to use a static IP address)

mount -t nfs -o proto=tcp,port=2049 /home/debian/CSharpCode

We should be good to go. We can test this by running a quick ls -l ~/CSharpCode command to see if the Development PC's files are now present and also by running an exe from a known project which was previously compiled over on the Development PC to see if the remotely compiled files are executable


Unmount the file system. We want this mapped filesystem to automatically mount up when the Beaglebone Black boots.

umount /home/debian/CSharpCode

edit the /etc/fstab so we mount automatically by adding the line   /home/debian/CSharpCode   nfs    auto  0  0

Reboot now to test this


At this point you should be able to create a new project (HelloWorldTest in this example) over on the Development PC, compile it and then switch to the Beaglebone Black and run that projects executable with a command like: mono ~/CSharpCode/HelloWorldTest/HelloWorldTest/bin/Debug/HelloWorldTest.exe. If you cannot do this you should figure out what is going wrong before proceeding to the next step. Any changes on the Development PC should always instantly appear and be executable over on the Beaglebone Black.

Running CSharp Executables On the Mapped Drive with a Shell Script

As mentioned in previous sections, rather than mapping each output directory from the C# projects on the remote Development PC, a entire directory tree with multiple projects was brought over. In order to execute the executable of a remotely compiled project either the current directory has to be changed to a many levels deep subdirectory or the files have to be prefixed with a path before execution. This is rather tedious and so, as a shortcut, I have created a number of shell scripts to do the job for me.

For example a project named BBBCSIOTest will have an output directory when mapped onto the Beaglebone Black of /home/debian/CSharpCode/BBBCSIOTest/BBBCSIOTest/bin/Debug/. I create a file in the CSharpCode subdirectory named runBBBCSIOTest which contains the following contents ...

#! /bin/sh

mono /home/debian/CSharpCode/BBBCSIOTest/BBBCSIOTest/bin/Debug/BBBCSIOTest.exe

... and this means that I can run that project executable with a simple command ./runBBBCSIOTest. Every project has its own shell script. This may seem like a rather trivial convenience - however in the next page in this series we will implement remote debugging and the command line for that is a bit more complex. You will definitely want to create an equivalent debugBBBCSIOTest to initiate the debugging rather than typing in all the command line options each time.


The contents of this web page are provided "as is" without any warranty of any kind and without any claim to accuracy. Please be aware that the information provided may be out-of-date, incomplete, erroneous or simply unsuitable for your purposes. Any use you make of the information is entirely at your discretion and any consequences of that use are entirely your responsibility. All source code is provided under the terms of the MIT License.