Hi There!
This post is about booting your linux from Network File System.
Network File System means that the uImage, rootfs and other files resides not on the target system but on some other host system connected with target system through network. Just to clear confusion, we will call the system which has uImage, rootfs and other files as host system whereas target system (BeagleBone Black in this case) is one the on which we want to boot Linux. This host system can be anywhere in the world. Usually we use our development system as host for NFS. We use NFS for development purpose because we get rid of flashing the target system or copying system image to SD card again and again. Although you may experience minor lags when you use NFS.
As mentioned in this post, we have our uImage, rootfs and other files ready.
Before cross compiling Linux kernel, please enable following flags in config file to add NFS support in kernel.
CONFIG_NFS_FS=y #NFS filesystem support
CONFIG_ROOT_NFS=y #Root file system on NFS
CONFIG_NET_ETHERNET=y #Ethernet
CONFIG_IP_PNP=y #IP: kernel level autoconfiguration
CONFIG_IP_PNP_DHCP=y #DHCP support
Host system configuration
NFS Kernel Server: This server will be used for keeping rootfs on NFS.
$ sudo apt-get install nfs-kernel-server #install nfs-kernel-server
$ mksdir nfsroot #create directory where rootfs will reside
$ vim /etc/exports #open this file and add following line in it.
<path to nfsroot> *(rw,sync,insecure,no_root_squash,no_subtree_check)
TFTP server: This server will be used to upload kernel image and dtb file to target system.
$ sudo apt-get install tftpd #install tftp server
$ vim /etc/xinetd.d/tftp #add following content to this file
service tftp
{
protocol = udp
port = 69
socket_type = dgram
wait = yes
user = nobody
server = /usr/sbin/in.tftpd
server_args = <path to tftpboot>
disable = no
}
$ sudo mkdir tftpboot #create tftpboot directory, this directory will have uImage, dtb and other files
$ sudo chmod -R 777 tftpboot #change permissions
$ sudo chown -R nobody tftpboot #change owner
DHCP server: This server will be used to allocate IP address to target machine.
$ sudo apt-get install isc-dhcp-server #install dhcp server
$ sudo vim /etc/default/isc-dhcp-server #add ethernet interface name to this file for which dhcp server will run. This can be different from "eth0" for your system
INTERFACES="eth0"
$ sudo vim /etc/dhcp/dhcpd.conf #add following configuration lines
subnet 192.168.100.0 netmask 255.255.255.0 {
range 192.168.100.10 192.168.100.25;
}
$ cp linux/arch/arm/boot/uImage tftpboot/ #copy uImage to tftpboot
$ cp linux/arch/arm/boot/dts/am335x-boneblack.dtb tftpboot/ #copy dtb file to tftpboot
$ sudo ifconfig eth0 192.168.100.1 netmask 255.255.255.0 #set IP address of host machine
$ sudo /etc/init.d/xinetd restart #restart xinetd
$ sudo service isc-dhcp-server restart #restart DHCP server
$ sudo service nfs-kernel-server restart #restart NFS server
$ sudo netstat -uap #check status of servers
Target system configuration
BeagleBone Black comes with a preinstalled U-Boot and Linux system in flash memory. Please ensure that U-Boot is working fine.
As soon as you switch ON the board, press any key to stop booting on U-Boot prompt.
U-Boot# setenv serverip 192.168.100.1
U-Boot# setenv a_uImage 0x82000000
U-Boot# setenv a_fdt 0x88000000
U-Boot# setenv initrd_high 0xffffffff
U-Boot# setenv dtbname am335x-boneblack.dtb
U-Boot# dhcp ${a_fdt} 192.168.100.1:${dtbname}
U-Boot# fdt addr ${a_fdt}
U-Boot# setenv fdt_high 0xffffffff
U-Boot# setenv bootargs ip=dhcp root=/dev/nfs rw nfsroot=192.168.100.1:<path to nfsroot>,nolock, wsize=1024, rsize=1024 rootwait console=ttyS0,115200n8 rootdelay=5
U-Boot# dhcp ${a_uImage} 192.168.100.1:uImage
U-Boot# bootm ${a_uImage} - ${a_fdt}
Your system will now boot and you should see Linux login prompt after few seconds.
I hope this post was helpful for you. Please share your queries, questions and feedbacks in comments section below.