2021-10-05 08:51:44 -07:00
|
|
|
|
---
|
|
|
|
|
title: "Booting a Raspberry Pi Over TFTP"
|
2021-10-05 19:55:02 -07:00
|
|
|
|
date: 2020-10-13T08:31:52-07:00
|
2023-12-18 11:22:14 -08:00
|
|
|
|
description: A writeup of how I set up a Raspberry Pi to boot over TFTP to facilitate an operating system development project.
|
2021-10-05 08:51:44 -07:00
|
|
|
|
series: ["Raspberry Pi OS Development"]
|
2022-10-12 10:55:50 -07:00
|
|
|
|
categories: ["Tech"]
|
|
|
|
|
tags: ["Raspberry Pi", "Networking"]
|
2021-10-05 08:51:44 -07:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
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
|
2022-10-12 10:55:50 -07:00
|
|
|
|
on the Raspberry Pi:
|
2021-10-05 08:51:44 -07:00
|
|
|
|
|
2022-10-12 10:55:50 -07:00
|
|
|
|
{{< figures/code >}}
|
|
|
|
|
```sh
|
2021-10-05 08:51:44 -07:00
|
|
|
|
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
|
2022-10-12 10:55:50 -07:00
|
|
|
|
```
|
2022-10-01 09:49:27 -07:00
|
|
|
|
{{< /figures/code >}}
|
2021-10-05 08:51:44 -07:00
|
|
|
|
|
2022-10-12 10:55:50 -07:00
|
|
|
|
My updated `bootconf.txt` is:
|
2021-10-05 08:51:44 -07:00
|
|
|
|
|
2022-10-12 10:55:50 -07:00
|
|
|
|
{{< figures/code >}}
|
|
|
|
|
```cfg
|
2021-10-05 08:51:44 -07:00
|
|
|
|
[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
|
2022-10-12 10:55:50 -07:00
|
|
|
|
```
|
2022-10-01 09:49:27 -07:00
|
|
|
|
{{< /figures/code >}}
|
2021-10-05 08:51:44 -07:00
|
|
|
|
|
|
|
|
|
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:
|
|
|
|
|
|
2022-10-12 10:55:50 -07:00
|
|
|
|
{{< figures/code >}}
|
|
|
|
|
```sh
|
2021-10-05 08:51:44 -07:00
|
|
|
|
sudo launchctl load -F /System/Library/LaunchDaemons/tftp.plist
|
|
|
|
|
sudo launchctl enable System/com.apple.tftpd
|
|
|
|
|
sudo launchctl start com.apple.tftpd
|
2022-10-12 10:55:50 -07:00
|
|
|
|
```
|
2022-10-01 09:49:27 -07:00
|
|
|
|
{{< /figures/code >}}
|
2021-10-05 08:51:44 -07:00
|
|
|
|
|
|
|
|
|
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!
|
|
|
|
|
|
2022-10-12 10:55:50 -07:00
|
|
|
|
The tftp server looks for files to serve out of **`/private/tftpboot`**, and those
|
2021-10-05 08:51:44 -07:00
|
|
|
|
things need to be world `rwx`, i.e. `777`. By default (this is configurable) the
|
2022-10-12 10:55:50 -07:00
|
|
|
|
Raspberry Pi queries for a directory named by its serial number.
|
2021-10-05 08:51:44 -07:00
|
|
|
|
|
2022-10-12 10:55:50 -07:00
|
|
|
|
{{< figures/code >}}
|
|
|
|
|
```sh
|
2021-10-05 19:55:02 -07:00
|
|
|
|
mkdir /private/tftpboot/$raspberry_pi_serial
|
2021-10-05 08:51:44 -07:00
|
|
|
|
chmod 777 /private/tftpboot
|
|
|
|
|
chmod -R 777 /private/tftpboot/*
|
2022-10-12 10:55:50 -07:00
|
|
|
|
```
|
2022-10-01 09:49:27 -07:00
|
|
|
|
{{< /figures/code >}}
|
2021-10-05 08:51:44 -07:00
|
|
|
|
|
2022-10-12 10:55:50 -07:00
|
|
|
|
Raspberry Pi looks for files of various names in that directory, one in
|
|
|
|
|
particular by the name of **`start.elf`**.
|
2021-10-05 08:51:44 -07:00
|
|
|
|
|
|
|
|
|
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
|
2022-10-12 10:55:50 -07:00
|
|
|
|
may be optional because you can also set `TFTP_IP` in the **`bootconf.txt`** above
|
2021-10-05 08:51:44 -07:00
|
|
|
|
to specify the IP directly. On my router:
|
|
|
|
|
|
2022-10-12 10:55:50 -07:00
|
|
|
|
{{< figures/code >}}
|
|
|
|
|
```sh
|
2021-10-05 08:51:44 -07:00
|
|
|
|
configure
|
|
|
|
|
set service dhcp-server shared-network-name LAN subnet $lan_cidr_subnet tftp-server-name $ip_of_mac
|
|
|
|
|
commit
|
|
|
|
|
save
|
|
|
|
|
exit
|
2022-10-12 10:55:50 -07:00
|
|
|
|
```
|
2022-10-01 09:49:27 -07:00
|
|
|
|
{{< /figures/code >}}
|
2021-10-05 08:51:44 -07:00
|
|
|
|
|
|
|
|
|
I also gave my Mac a static IP, and renewed the DHCP lease so it took the new IP
|
2022-10-12 10:55:50 -07:00
|
|
|
|
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.
|
2021-10-05 08:51:44 -07:00
|
|
|
|
|
|
|
|
|
## 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
|
2022-10-01 09:49:27 -07:00
|
|
|
|
[mac-tftp]: https://www.unixfu.ch/start-a-tftp-server-on-your-mac/
|