--- title: "Booting a Raspberry Pi Over TFTP" date: 2020-10-13T08:31:52-07:00 draft: false series: ["Raspberry Pi OS Development"] categories: ["Tech"] tags: ["Raspberry Pi", "Networking"] --- In order to do this, I modified the [EEPROM bootloader][eeprom] bootloader according to the instructions in the Raspberry Pi documentation. That page is also on [GitHub][eeprom-gh] which might be a more stable location. On Raspbian on the Raspberry Pi: {{< figures/code >}} ```sh fw=/lib/firmware/raspberrypi/bootloader/stable/pieeprom-2020-09-03.bin rpi-eeprom-config $fw > ~/bootconf.txt vi ~/bootconf.txt rpi-eeprom-config --out ~/pieeprom-new.bin --config ~/bootconf.txt $fw sudo rpi-eeprom-update -d -f ~/pieeprom-new.bin sudo reboot ``` {{< /figures/code >}} My updated `bootconf.txt` is: {{< figures/code >}} ```cfg [all] BOOT_UART=1 WAKE_ON_GPIO=0 POWER_OFF_ON_HALT=0 DHCP_TIMEOUT=45000 DHCP_REQ_TIMEOUT=4000 TFTP_FILE_TIMEOUT=30000 ENABLE_SELF_UPDATE=1 DISABLE_HDMI=0 BOOT_ORDER=0xf412 ``` {{< /figures/code >}} I enabled UART debugging, and set the boot order to be: network `0x2`, SD card `0x1`, USB mass storage `0x4`, and finally reboot `0xf`. These steps need to be repeated if the bootloader is updated via apt. I [enabled the TFTP server][mac-tftp] on my Mac: {{< figures/code >}} ```sh sudo launchctl load -F /System/Library/LaunchDaemons/tftp.plist sudo launchctl enable System/com.apple.tftpd sudo launchctl start com.apple.tftpd ``` {{< /figures/code >}} I’m not sure if the `enable` command is actually necessary. This doesn't actually start the `tftpd` daemon. Instead, macOS starts the daemon on demand when it notices an incoming tftp request on the network. Don't be alarmed! The tftp server looks for files to serve out of **`/private/tftpboot`**, and those things need to be world `rwx`, i.e. `777`. By default (this is configurable) the Raspberry Pi queries for a directory named by its serial number. {{< figures/code >}} ```sh mkdir /private/tftpboot/$raspberry_pi_serial chmod 777 /private/tftpboot chmod -R 777 /private/tftpboot/* ``` {{< /figures/code >}} Raspberry Pi looks for files of various names in that directory, one in particular by the name of **`start.elf`**. Next, I had to update my Ubiquiti router's DHCP server configuration (on the command line) to pass a `tftp-server` parameter in the DHCP payload. This step may be optional because you can also set `TFTP_IP` in the **`bootconf.txt`** above to specify the IP directly. On my router: {{< figures/code >}} ```sh configure set service dhcp-server shared-network-name LAN subnet $lan_cidr_subnet tftp-server-name $ip_of_mac commit save exit ``` {{< /figures/code >}} I also gave my Mac a static IP, and renewed the DHCP lease so it took the new IP to make the whole process a little more smooth. Now, it appears the Raspberry Pi will attempt a TFTP boot, and I see queries in the logs on my Mac. ## Further Reading * [Hackaday's Raspberry Pi Boot Sequence Guide](https://hackaday.io/page/6372-raspberry-pi-4-boot-sequence) * [Linuxhit Guide to Booting a Raspberry Pi with PXE](https://linuxhit.com/raspberry-pi-pxe-boot-netbooting-a-pi-4-without-an-sd-card/) [eeprom]: https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711_bootloader_config.md [eeprom-gh]: https://github.com/raspberrypi/documentation/blob/master/hardware/raspberrypi/bcm2711_bootloader_config.md [mac-tftp]: https://www.unixfu.ch/start-a-tftp-server-on-your-mac/