RPi Network Boot 2nd Edition

3 years ago I’d written about booting the Raspberry Pi over NFS, which in the end didn’t full work so that I had to use a SD card to store the cmdline.txt that allowed to mount the root filesystem over NFS. While the SD card is only used read-only, there’s still the need for the SD card and the risk of a card failure.

I’ve decided to give it a new try, as I was setting up a new RPi. In short: it now works as expected, but there were many caveats.

initial setup

Main inspiration came from an online article in Raspberry Pi geek 2018/02

Raspberry network boot mode has to be enabled by adding the line program_usb_boot_mode=1 to /boot/config.txt and rebooting. The enabling has to be checked : the following command must return the value 3020000a.

1
2
$ vcgencmd otp_dump | grep 17
17:3020000a

Extracting content of image

Instead of rsync’ing the content of a SD card, I found the method to extract the content of and ISO image, as provided by the various distributions

  • fsdisk -l
  • multiply the “start sector” information by 512 (512 bytes / sector) to get the offset
  • mount -o loop,offset= /mnt
  • repeat for all partitions (typically the /boot and /)

Important is also to edit the /etc/fstab, in order to remove the 2 lines mounting the / and /boot - they’ll come over through NFS. Adapting /etc/hostname may also be a good idea!

TFTP setup

A nice feature of the RPi upon NFS boot : it requests /start.elf (with being the MAC address without the “:”). If not found, it moves on with start.elf. If found, it the assumes all further files needed during boot are also present in this directoy (especially cmdline.txt). Combined with symlinks, it allows to have different cmdline.txt or config.txt, while keeping the other files common for multiple RPi’s.

cmdline.txt

My final cmdline looks is

1
dwc_otg.lpm_enable=0 console=tty1 root=/dev/nfs rootfstype=nfs nfsroot=192.168.1.1:/export/tftp/raspbian-lite,vers=3,rsize=32768,wsize=32768 rw ip=dhcp rootwait elevator=deadline dtparam=sd_poll_once=on modprobe.blacklist=bcm2835_v4l2

The import stuff here is :

  • root=/dev/nfs rootfstype=nfs : this tells toperform network boot
  • nfsroot=192.168.1.1:/export/tftp/raspbian-lite,vers=3 : path to the root filesystem, using NFSv3 protocol
  • dtparam=sd_poll_once=on : perform only 1 trial access to the (missing) SD card

Keeping single /boot

The NFS boot procedure requires access to the /boot content through TFTP, and then the whole filesystem must be NFS-mounted. Later is important so that the /boot content is updated by apt. However, if network-booting multiple RPi’s, it’s not possible to use the same directory tree for both the NFS export and the TFTP. Fortunately, TFTP is following symlinks, therefore the /boot content can be symlinked from the NFS directory tree into the TFTP tree. This further allows to have the various overlays up to date and available during boot.

Also a good idea to touch /boot/ssh - wil activate the SSH server upon boot, so that remote login is possible

System update

The system was running, last action was to run an apt update && apt upgrade command. The raspbian-lite image I’d used was only few days old, but before going further with the system, I wanted to make sure it was fully up-to-date. Unfortunately, the update resulted in the system no longer booting!

The solution was to remove the udp parameter passed in the nfsroot argument

  • old : nfsroot=192.168.1.1:/export/tftp/raspbian-lite,vers=3,udp,rsize=32768,wsize=32768
  • new : nfsroot=192.168.1.1:/export/tftp/raspbian-lite,vers=3,rsize=32768,wsize=32768

So: take care of “old” instructions found on the internet!

With this issue fixed, the system was still not fully booting, rather segfault’ing with some messages indicating that the network interface had issues, thus the root filesystem (mounted through NFS) was lost.

Finally found the solution (also here) : disable the video (and webcam) stuff by adding modprobe.blacklist=bcm2835_v4l2 to the cmdline.txt. The issues seems only to occur when performing NFS boot :-(