Overview
Back when I was working with kernel 3.2 and the TI Linux SDK, I had the Beaglebone booting to a NFS. I thought it would be nice to do that again, because it is very convenient for development purposes.Downloads
Get this if you don't already have a micro SD card with an image on it:Debian eMMC Flasher (can also be used as a live system): Official Image, Other Versions
Background
I will break up the configuration into three parts:- TFTP
- NFS
- Local bootstrap
TFTP
TFTP is a popular method of booting IP phones, routers, and net boot capable PCs. It provides a simple way to download files to clients. TFTP requires a server to be running somewhere on the network, though. This can be a Linux system or your fancy home router (DD-WRT, tomato, or other custom firmware).TFTP is easy to install on an Ubuntu host:
> sudo apt-get install xinetd tftpd tftp
Unlike most installs, this does not create a default configuration. So you have to create the following:
> sudo nano /etc/xinetd.d/tftp
and enter the following into the file:
service tftp
{
protocol = udp
port = 69
socket_type = dgram
wait = yes
user = nobody
server = /usr/sbin/in.tftpd
server_args = /tftpboot
disable = no
}
This will configure the service to reside on port 69 and serve files from the root folder /tftpboot. Since /tftpboot doesn't exist, let's create this folder now, populate it with boot binaries, set permissions, and restart the service:
> sudo mkdir /tftpboot
> sudo chmod -R 777 /tftpboot
> sudo chown -R nobody /tftpboot
> sudo /etc/init.d/xinetd restart
NFS
NFS stands for network file system. It has been around a while (the 80's) and is easy to setup on an existing Linux host.First we have to install the NFS server on our host:
> sudo apt-get install nfs-kernel-server
Next we need to populate a root filesystem. You could use the image-builder scripts from Robert C Nelson, but those require lots of harddrive space and time. A faster way is to copy an already generated image. I chose to use a micro SD card with the eMMC image because I had one laying around.
- Use a card reader to mount the SD card in the Ubuntu host.
- Copy the root file system to a host folder and copy boot files to our TFTP folder:
> sudo cp -a /media/eMMC-Flasher/* /home/programmer/bbb_nfs_root
> sudo cp /media/BEAGLE_BONE/initrd.img /tftpboot
> sudo cp /media/BEAGLE_BONE/zImage /tftpboot
> sudo cp /media/BEAGLE_BONE/dtbs/am335x-boneblack.dtb /tftpboot
You may have to change the am335x-boneblack.dtb file to match your system, for example a BBW. Browse the dtbs folder for options.
Once you have a full rootfs folder, you now need to tell the server where to look by modifying the /etc/exports file:
> sudo nano /etc/exports
Add this line (modify the path to point to your rootfs):
/home/programmer/bbb_nfs_root *(rw,nohide,insecure,no_subtree_check,async,no_root_squash)
NOTE: Ensure that there is a space between rootfs and *, but no space between * and (rw,nohi.....
Save and exit, and then restart the NFS server, so our folder will get served up:
> sudo /etc/init.d/nfs-kernel-server restart
Local Bootstrap
Now that the server is configured, we need to tell the Beaglebone to boot from the network.First, a little background on the Beaglebone filesystem. The AM335x can get its initial image from a number of sources. The Beaglebone White used a uSD card, while the Beaglebone Black can use a uSD card or the on-board eMMC. Either way, the partitioning is the same: one small FAT boot partition and an EXT root partition that fills up the rest of the space.
The Beaglebone Linux images use Das uBoot as their bootloader (versus LILO or GRUB found on typical desktop systems). uBoot takes care of initializing low level hardware and provides filesystem drivers to aide in booting the main operating system. On the Beaglebones, uBoot can be run interactively, through the console serial port, or it can be scripted through a file called uEnv.txt. So, in order to boot a NFS, all we need to do is create a specially crafted uEnv.txt file.
The easiest way to modify the uEnv.txt file is to use a USB connection to a host PC. Any host will work, as we only need to modify the files that mount automatically as a mass storage device. For this to work, though, you need to have an initial image booting the Beaglebone. Any image (Angstrom/Debian/etc) will work, as long as it uses uBoot and uEnv.txt.
I highly recommend using a micro SD card image until you get the uEnv.txt settings nailed down. It is much easier to use a card reader, to modify the files on a host, than it is to try to get the Beaglebone booting again (it needs to boot in order to start the mass storage driver). If you still insist on using the eMMC, you should be familiar with the serial console, because you are going to need it.
After several failed attempts, here is my golden uEnv.txt file. Change the IP addresses and rootpath to match your configuration. I could not get DHCP to work, so I assigned ipaddr to be outside of the range of my DHCP server. This IP is only used for the TFTP process and once the operating system is up and running, it will reinitialize the Ethernet and get a DHCP address.
serverip=192.168.1.100
ipaddr=192.168.1.55rootpath=/home/programmer/bbb_nfs_root
# Choose one...#mmcORtftp=load mmc ${mmcdev}:${mmcpart}mmcORtftp=tftp
# Original Configsloadaddr=0x80300000initrd_addr=0x81600000fdtaddr=0x815f0000initrd_high=0xfffffffffdt_high=0xffffffff
systemd=quiet init=/lib/systemd/systemdmmcrootfstype=ext4 rootwait fixrtcconsole=ttyO0,115200n8kernel_file=zImageinitrd_file=initrd.img
loadkernel=${mmcORtftp} ${loadaddr} ${kernel_file}loadinitrd=${mmcORtftp} ${initrd_addr} ${initrd_file}; setenv initrd_size \ ${filesize}loadfdt=${mmcORtftp} ${fdtaddr} ${fdtfile}loadfiles=run loadkernel; run loadinitrd; run loadfdt
mmcargs=setenv bootargs console=${console} root=/dev/nfs \ nfsroot=${serverip}:${rootpath},nolock ${systemd}uenvcmd=run loadfiles; run mmcargs; bootz ${loadaddr} \ ${initrd_addr}:${initrd_size} ${fdtaddr}
Enjoy testing new Kernels, unzipping large files with the host processor, and taking advantage of the massive storage capacity of your host hard drive :)
Sources:
http://processors.wiki.ti.com/index.php/Booting_Linux_kernel_using_U-Boot
http://processors.wiki.ti.com/index.php/Alternate_Boot_Methods_for_OMAP-L137/DA830#Mounting_Root_File_System
http://askubuntu.com/questions/201505/how-do-i-install-and-run-a-tftp-server
Sadly this does not appear to work with the latest debian build.
ReplyDeleteI thought It was due to changes in the adresses used in the latest uEnv.txt which now reads;
loadaddr=0x82000000
initrd_addr=0x88080000
fdtaddr=0x88000000
But making these changes did not help.
The SD card boot hangs with 4 leds on and the mmc boot boots into the mmc, ignoring both the SD card and the NFS instructions. I've checked the NFS server by mounting it from a working SD boot as follows (with your parameters substituted)
sudo mount 192.168.10.10:/home/programmer/bbb_nfs_root /mnt/nfs
ls /mnt/nfs
bin boot dev etc home lib lost+found media mnt opt ...
Any ideas where I have gone wrong?
Thanks
I know this is old but still very useful. Simple changes will make it work with Debian 9.x. To copy files you need the following in /tftpboot from the sd card. /rootfs/boot/vmlinuz-[build number], /rootfs/boot/initrd.img-[build number], and the directory /rootfs/boot/dtbs. Then copy the entire rootfs directory to the bbb_nfs_root directory using sudo cp -a. For the uEnv.txt file on the BBB you only need the following:
ReplyDeleteclient_ip=172.16.0.72
server_ip=172.16.100.50
#gw_ip=172.16.0.1
netmask=255.255.0.0
hostname=BBB
device=eth0
autoconf=off
root_dir=/home/[username]/programmer/bbb_nfs_root/rootfs
nfs_options=,vers=3
jfsrootfstype=ext4 rootwait fixrtc
nfsroot=${server_ip}:${root_dir}${nfs_options}
uname_r=4.14.108-ti-r113
#uuid=
dtb=am335x-boneblack-uboot-univ.dtb