LinuxCNCKnowledgeBase | RecentChanges | PageIndex | Preferences | LinuxCNC.org

Getting the Beaglebone board to work for LinuxCNC development, the Easy Way

I've prepared a complete root filesystem for the beaglebone with all batteries included to boot/run from a server. This is a bit different from the setup as distributed - where everything runs from a SD card, including the root filesystem. While this is fine for a packaged runtime, it is abysmally slow to compile and build any non-trival piece of software. Hence the choice to run from an NFS server - this is really a developer setup.

I assume we will have a SD card image to just run an application shortly.

The parts are:

All that needs to be done to run/develop on this platform is:

While it does help to read README.the-hard-way most of this isnt needed anymore, except for the server setup and bb boot config steps. I just repeat these steps here so this is self-contained

<KARnote: I've sprinkled some notes throughout, delimited by angle brackets like this note is - KAR, 20121229>

<KARnote: While this page addresses just Michael's installation of the parts named above, it should be obvious that other distributions can be added. For example, on my server, I have Michael's system alongside the elinux.org Quantal 12.10 armhf distribution (see http://elinux.org/BeagleBoardUbuntu), and I'm adding others. Each can be booted to my BeagleBone with only a change to a stanza to my dhcpd.conf file on my server, a dhcp restart, and a press of the boot button on the BeagleBone. I'm sure a clever programmer could make this even easier but, in any case, it means no more fiddling with microSD cards. Slick.>


We need: root filesystem unpacked, DHCP, TFTP, and NFS server set up

<KARnote: for Ubuntu 10.04LTS users, the packages are dhcp3-server, tfptd-hpa (or tftp-hpa; I think both install the server daemon), and nfs-kernel-server. While Michael describes running all these services on a single host, It should be obvious that the various services can be running on different hosts mutatis mutandi.>

NFS root filesystem setup

first, fetch the root filesystem archive like so:

 wget http://static.mah.priv.at/public/beaglebone/rootfs.tar.xz

ca 900MB - it will occupy some 2GB once expanded.

This archive needs to be unpacked under the directory exported by TFTP since the kernel is loaded by TFTP directly from boot/vmlinuz... so TFTP must be able to access it.

lets assume your TFTP directory is /tftpboot . That means that files can be fetched via TFTP relative to /tftpboot.

<KARnote: Ubuntu is all over the map concerning default locations for server directories. With 10.04LTS, you'll find that tftpd-hpa assumes a default /var/lib/tftpboot while dhcp3-server assumes /srv/.... Other servers used yet other directories. The Linux Hierarchy Standard suggests all such directories should be in /srv/... and I assume that's the direction distributions are moving. Don't worry about it. None of the assumptions are cast in stone. Just be very consistent throughout your configuration files.>

Create a directory underneath and unpack the rootfs archive:

 $ sudo bash
 # mkdir /tftpboot/rootfs 
 # cd /tftpboot/rootfs
 # tar Jxf <wherevever>/rootfs.tar.xz

The xenomai kernel image should now have the path /tftpboot/rootfs/boot/vmlinuz-3.2.21-xenomai+ .

<KARnote: there are several files in this archive that can cause trouble because they contain information specific to Michael's system. I recommend deleting the following two files once the archive has been unpacked (please note the paths are relative to the head of the archive):


DHCP setup

The dhcp server not only sets up IP, but also passes the kernel image which gets shoved down with TFTP, and the NFS rootfs mount point to the boot loader.

I assume you have isc-dhcp-server installed.

The dhcp server configuration is in /etc/dhcpd/dhcp.conf .

<KARnote: For the dhcp3 server in Ubuntu 10.04LTS this is /etc/dhcp3/dhcpd.conf>

It has a 'subnet description' which applies to the whole network, and I use static assignments for the clients in this case although thats not strictly necessary.

<KARnote: Although all this works in principle with dynamic host IP assignments, even the server developers strongly advise against it. Also, I reiterate a comment buried in the following example configuration. If the 'pool' option is omitted, then the DHCP server being set up here can function on the same subnet without interference with another DHCP server which is handing out dynamic host IP addresses, as does, for example, the router/access point on my home network. Just be sure any static IPs being assigned here don't fall in the range of dynamic IP addresses known to the other DHCP server.>

Assuming the network is and the linux server is at 192.168.126.__FIXME__ this should read like so:

subnet netmask {

  # example for a dynamic range of DHCP clients
  # (affects only hosts which arent explicitly stated below)
  # not needed if you have some other DHCP server (DSL/Cable modem)
  # in that case, comment out
  pool {
  option subnet-mask;
  option broadcast-address;

  # replace  by default gateway	(DSL/Cable modem IP address)
  option routers 192.168.126.__FIXME__;          
  option domain-name "stiwoll.mah.priv.at";                # replace by domain if applicable
  option domain-name-servers 192.168.126.__FIXME__, <nameserver>; # replace by domain name servers
  option interface-mtu 1500;
  option log-servers  192.168.126.__FIXME__;                      # replace by syslog server if applicable
  option ntp-servers  192.168.126.__FIXME__,;        # replace by NTP (time) servers if applicable 
 # pxe boot
  # http://www.debian-administration.org/article/478/Setting_up_a_server_for_PXE_network_booting
  # filename "pxelinux.0";                                 # for netbooting via PXE

  # IMPORTANT: this is the TFTP server address! no default here or
  # TFTP booting fails
  next-server 192.168.126.__FIXME__;   # replace by TFTP server address

Next figure out the MAC address of your Beaglebone (there's a sticker on it) <KARnote: my sticker shows only a serial number!> and edit a stanza for the BB (I do this because I have several and with dynamic IP addresses I never know who is who):

adapt MAC address, IP addresses and pathnames as needed <KARnote: here fixed-address is Michael's chosen static IP assignment for his BeagleBone>:

host bb2 {
        # replace by BB MAC address 
        hardware ethernet   00:18:31:8e:ee:41;  

	# if you want your linux server to act as remote syslog
	# server, add the following to /etc/rsyslog.conf 
	# # provides UDP syslog reception
	# $ModLoad imudp
	# $UDPServerRun 514

	# after which this option makes sense:
        option log-servers  192.168.126.__FIXME__;

	# filename points to the kernel image which is loaded via 
	# TFTP by uboot -
        filename "rootfs/boot/vmlinuz-3.2.21-xenomai+";

        # 'rootfs' is the NFS mount point,
	# so I'm fetching the kernel from its standard location in the
	# ubuntu directory

	# the NFS mount path for the root filesystem. Uboot 
	# passes this to the kernel command line.
	# this is in essence the mount command argument executed by
	# the booting kernel as it tries to mount the rootfs

        option root-path "192.168.126.__FIXME__:/tftpboot/rootfs";


On the filename parameter:

This is a pathname as the TFTP server 'sees it' after doing a chroot into TFTP_DIRECTORY="/tftpboot" (see next section)

Example: assume you have /tftpboot as exported TFTP directory, and the root filesystem is unpacked in /tftpboot/rootfs .

In that case the absolute pathname of the kernel image *on the server* will be /tftpboot/rootfs/bootvmlinuz-3.2.21-xenomai+

Since the TFTP server chroots into /tftpboot, the pathname as seen by the TFTP server is "rootfs/bootvmlinuz-3.2.21-xenomai+" and that is what goes into the "filename" parameter - the boot image

On the root-path parameter

This is the mount path for NFS mounting from a client - you should be able to execute on some other box

 $ sudo mkdir /mnt/testrootfs
 $ sudo mount.nfs 192.168.126.__FIXME__:/tftpboot/rootfs /mnt/testrootfs

and succeed.

Wrapping up DHCP config


 $ sudo /etc/init.d/isc-dhcp-server restart

or, depending on linux version, this might also be:

 $ sudo service isc-dhcp-server restart

after editing and make sure the isc server comes up - it should also log in /var/log/messages (I think, maybe some other logfile like daemon.log)

<KARnote: For the dhcp3 server on Ubuntu 10.04LTS, use

 $ sudo service dhcp3-server restart


TFTP setup:

I use the tftp-hpa package. The config file is /etc/default/tftp-hpa and should read:

 TFTP_DIRECTORY="/tftpboot"   # adapt as needed
 TFTP_OPTIONS="-vvvv --secure"

Also restart the tftp server if she's running to make sure the new configuration is honoured

In my case this works like so:

 $ sudo /etc/init.d/tftpd-hpa restart

depending on your linux version, this might also be:

 $ sudo service tftpd-hpa restart

For ubuntu-12.04, put a new script /etc/network/if-up.d/tftpd-hpa which contains:

 restart tftpd-hpa

And, chmod 755 the script.

tftp-hpa not start at boot: https://bugs.launchpad.net/ubuntu/+source/tftp-hpa/+bug/972845

NFS server setup

This needs the nfs-kernel-server package.

/etc/exports reads like so:


NB: this is a very permissive setting. It allows any client in 192.168.126/24 to mount /tftpboot as read/write.

<KARnote: no whitespace between the address range and the left parenthesis, please. It's an easy mistake for the unwary that causes no end of mischief.>

after editing, run this:

 $  sudo exportfs -a 

'showmount' should give a list of clients which have this server mounted.

BB Serial console

This is needed to monitor/change the boot process and see what this thing is doing.

The MicroUSB port on the bb creates to USB serial devices if connected to a host (MacOS X in my case, but shouldnt matter). One is the actual serial console, the other I understand to be a JTAG port which I havent tried. You need to figure the device names, on Linux they are likely ttyUSB0/ttyUSB1; on my Mac they are different. To connect to the console, I use this command:

 screen /dev/tty.usbserial-TIVSO45RB 115200

Besides the two ttys, also the first of the two partitions on the SD card should become visible in the host (it's a vfat partition)

<KARnote: On my Ubuntu and Mint systems, the command is

 $ sudo screen /dev/ttyUSB1 115200

and the vfat partition is mounted as /media/BEAGLE_BONE which means it pops up on my GNOME desktop as BEAGLE_BONE.

Besides screen, other terminal communications programs that are known to work include kermit (if you worked with microcomputers in the 1980s you certainly know kermit!), minicom, and GtkTerm. Each has its own peculiarities.>

Booting the Beaglebone via TFTP

I suggest copying the SD card before modifying it so you can step back if something goes wrong. You need to replace a file and edit the uEnv.txt file in the BB boot partition (the first small VFAT partition). I do this by inserting the SD card into my Mac and doing the edit there.

<KARnote: I got tired of removing the microSD card and inserting it into a USB card reader. Once the BB-provided Angstrom system has booted one can edit the uEnv.txt file in situ from a Linux system via the /media/BEAGLE_BONE mount mentioned above. If the card is edited separately then the desired files are those in the BEAGLE_BONE partition. Don't get confused by any like-named files which exist in the /boot directory in the Angstrom partition. Alternatively, once the Angstrom system has booted log into it and do the following to mount the partition:

 $ mount -t vfat /dev/disk/by-label/BEAGLE_BONE /media/BEAGLE_BONE

and use some editor (vi is there for sure) to edit uEnv.txt (the mountpoint /media/BEAGLE_BONE was already defined in the BB-provided Angstrom system on my microSD card.

Later, when running Michael's distribution, you should find the microSD-card boot partition mounted at /boot/uboot.

Of course it is always possible some mistake in editing will prevent the BeagleBone from rebooting, in which case it's back to removing the card yada yada yada.>

The bootloader which comes with the BB is configured to use the SD card only, so we need to reconfigure it. Also, the u-boot.img file which you find in the boot partition is built to execute what is called a 'uimage' file - a kernel wrapped in a uboot-specific header. However, recently a new command 'bootz' was added to uboot which allows to boot unmodified zImage files as they are generated by the kernel build if you run 'make zImage'. That's much more convenient and one step less to fail, so we'll use that. So we need to do this:

  supports the 'bootz' command

To replace the u-boot.img use this file - this one understands 'bootz':

 $ wget http://static.mah.priv.at/public/beaglebone/u-boot.img

<KARnote: the u-boot.img file should be paired with its MLO file, else mysterious errors may occur. Michael had subsequently tar'red up all three (MLO, u-boot.img, uEnv.txt) and placed them on his server:


The MLO file *must* be written first to the boot partition. See, e.g., http://elinux.org/BeagleBoardBeginners. Also, I've begun documenting my adventures with my BBone, including more details about U-Boot, at https://sites.google.com/site/manisbutareed/bringing-my-beagles-to-heel >

Step 2 is editing the uEnv.txt boot script - mine is generic and reads so:

 bootargs=console=ttyO0,115200n8 run_hardware_tests root=/dev/nfs rw noinitrd debug ip=dhcp rootdelay=2 --no-log
 uenvcmd=echo "Booting from Network"; dcache off; dhcp; tftp ${loadaddr}; bootz ${loadaddr}

<KARnote: That's tty<letter-O><number-0> >

<mah note: the 'dcache off;' parameter is not understood by this version of uboot, useless and can be deleted, >

Note this setup completely bypasses the second partition (the rootfs) - that will be replaced by the nfs rootfs.

Save it, eject and insert into Beaglebone SD slot, press reset.

You might watch the boot process on the server by doing this:

 $ sudo tail -f /var/log/daemon.log 

A successful boot sequence looks like so in my /var/log/daemon.log:

 # the DHCP 'get IP address and boot parameters' phase:
 Dec 28 15:36:29 bb2 dhclient: DHCPREQUEST of on eth0 to port 67
 Dec 28 15:36:29 bb2 dhclient: DHCPACK of from
 Dec 28 15:36:30 bb2 dhclient: bound to -- renewal in 13534 seconds.

 # the 'load kernel image via TFTP phase':
 Dec 28 22:46:33 alix in.tftpd[5866]: RRQ from filename foo/boot/vmlinuz-3.2.21-xenomai+

 # the root filesystem gets NFS mounted:
 Dec 28 22:46:45 alix rpc.mountd[3172]: authenticated mount request from for /mnt/WDC500GB/tftpboot/foo (/mnt/WDC500GB)

The console log should read like so:

reading u-boot.img
reading u-boot.img

U-Boot 2012.10-dirty (Nov 26 2012 - 12:45:53)

I2C:   ready
DRAM:  256 MiB
WARNING: Caches not enabled
Using default environment

Net:   cpsw
Hit any key to stop autoboot:  0 
SD/MMC found on device 0
reading uEnv.txt

216 bytes read
Loaded environment from uEnv.txt
Importing environment from mmc ...
Running uenvcmd ...
Booting from Network
Unknown command 'dcache' - try 'help'
cpsw Waiting for PHY auto negotiation to complete. done
link up on port 0, speed 100, full duplex
BOOTP broadcast 1
BOOTP broadcast 2
DHCP client bound to address
link up on port 0, speed 100, full duplex
Using cpsw device
TFTP from server; our IP address is
Filename 'rootfs/boot/vmlinuz-3.2.21-xenomai+'.
Load address: 0x80200000
Loading: #################################################################
Bytes transferred = 2061360 (1f7430 hex)

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Linux version 3.2.21-xenomai+ (mah@precise) (gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #22 PREEMPT Fri Dec 28 00:18:46 CET 2012
[    0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c53c7d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[    0.000000] Machine: am335xevm
[    0.000000] Memory policy: ECC disabled, Data cache writeback
[    0.000000] On node 0 totalpages: 65536
[    0.000000] free_area_init_node: node 0, pgdat c059fd8c, node_mem_map c0616000
[    0.000000]   Normal zone: 512 pages used for memmap

Ubuntu 12.04.1 LTS arm ttyO0

arm login: 

login as user linuxcnc password linuxcnc

 $ cat /proc/xenomai/stat
 CPU  PID    MSW        CSW        PF    STAT       %CPU  NAME
  0  0      0          0          0     00500080  100.0  ROOT
  0  0      0          150132     0     00000000    0.0  IRQ68: [timer]

looks we're in business!

<KARnote: While I succeeded in reproducing a network-booting system ala Michael's recipe, my system works for less than 5 minutes before becoming catatonic---no serial port or ethernet communication. It's been suggested this is occurring because I've been powering my BeagleBone via the microUSB port but I'm now powering it from a 5V supply via the 5V bayonet plug and still suffering the problem. I'm looking into it. 20130101>

Before running LinuxCNC with a remote display works, you might have to do the following on the PC:

Now log into the beaglebone

edit .bashrc near the bottom:

Running headless X via VNC

One way I got this to work (maybe not optimal) is:

 $ sudo apt-get install tightvncserver

then start from commandline like so:

mah@bb2:~$ vncserver 

You will require a password to access your desktops.

Would you like to enter a view-only password (y/n)? n

New 'X' desktop is bb2:1

Starting applications specified in /home/mah/.vnc/xstartup
Log file is /home/mah/.vnc/bb2:1.log

You can now connect to that screen through VNC ip-address-of-bb:5901 .

optional steps

Swap setup:

To compile the rtos-integration-preview3-merged-into-master branch, swap is needed - I use swapping into a file in the NFS filesystem - not fast, but no extra swap device needed. Follow these guidelines:


 Alternatively, a USB stick works fine too.

<mah note: strike that out. I got panics with swapping to an USB stick, and have no such problems if swapping to a swapfile on the sd card as per below: >

Swapping to local file is more stable than NFS mounted one. Here are steps to create 1GB swap file on SD card:
/dev/mmcblk0p2 /mnt/mmcp2 auto defaults 0 0
/mnt/mmcp2/var/cache/swap/swapfile none swap sw 0 0
sudo mount /mnt/mmcp2
sudo mkdir -p /mnt/mmcp2/var/cache/swap/   
sudo dd if=/dev/zero of=/mnt/mmcp2/var/cache/swap/swapfile bs=1M count=1024
sudo chmod 0600 /mnt/mmcp2/var/cache/swap/swapfile
sudo mkswap /mnt/mmcp2/var/cache/swap/swapfile
sudo swapon /mnt/mmcp2/var/cache/swap/swapfile

Kernel rebuild

please see



<KARnote: While we're still in this shakedown phase it is especially important to report all relevant information about a misbehaving system INCLUDING the revision of the BeagleBone we're using. I'm just as guilty as everyone else in neglecting this (mine is a late-model Rev. A6) but it can be truly helpful.>

<bas reports>: I did run into all the usual DHCP and NFS problems, one of these may be worth mentioning on your wiki page:

Mounting the root fs gave intermittent NFS server timeouts / NFS server ok messages. The solution was not that obvious, disabling the /dev/mmcblk* mounts in the /etc/fstab file solved the NFS problems!

<mah note>: Kent had noticed the kernel does not have ext2/3/4 support compiled in but as a module, and since the boot process doesnt use an initrd image this kernel cannot boot from SD card.

I changed this in the kernel config here: http://git.mah.priv.at/gitweb/linuxcnc-kernel.git/commit/89476fc67154a457555d89e2d195825953814a52

In theory this kernel should boot from SD card; the new binaries are here: http://static.mah.priv.at/public/beaglebone , the updated files are

http://static.mah.priv.at/public/beaglebone/linux-3.2.21-xenomai+-headers.tar.gz http://static.mah.priv.at/public/beaglebone/linux-3.2.21-xenomai+.tar.gz

I also repackaged the rootfs in http://static.mah.priv.at/public/beaglebone/rootfs.tar.xy

<KARnote: Ummm. This is an xz file. Some decompressors may object to the .xy suffix in which case just change it and drive on. I can confirm that this kernel can boot from a microSD card and mount the rootfs from the second partition. Thanks. 20130116>

it's just the above kernel tar files expanded into it and an old dhcp lease file removed which gave troubles

<KARnote: Until Michael gets a chance to edit the rootfs distribution, there's a minor bug that can lead to the following error message during kernel initialization

 udevd[136]: error changing net interface name eth0 to eth1: Device or resource busy

This does not halt initialization but I find any error messages distracting. The offending file is /etc/udev/rules.d/70-persistent-net.rules which contains a line like

 SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:18:31:8f:4f:e4", ATTR{dev_id}=="0x0",ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

The fix is to delete or comment out this line before first mounting the rootfs.

If you've already used this filesystem, the offending file will contain a second, similar line with your own board's MAC address and NAME="eth1". In this case, both delete or comment out the first line and change "eth1" to "eth0" in the second. The error message should no longer occur. 20130124>

X11 Forwarding Error
Solution: add "X11UseLocalhost no" to "/etc/ssh/sshd_config".

'Xenomai: binding failed: Operation not permitted.'
Solution: add user to group 'xenomai', logout, login, see also http://www.xenomai.org/index.php/Non-root_RT

open(/dev/mem): permission denied
Solution: add user to group 'kmem', logout, login

Alternatve Xenomai Kernels for the BeagleBone

I recently found this: http://yapatel.org/wiki/index.php/Installing_Xenomai_on_a_beaglebone - no idea how good it works. -m

LinuxCNCKnowledgeBase | RecentChanges | PageIndex | Preferences | LinuxCNC.org
This page is read-only. Follow the BasicSteps to edit pages. | View other revisions
Last edited October 26, 2017 12:56 pm by KimK (diff)
Published under a Creative Commons License