Raspberry Pi 4 を PXE + SSD Boot する
悲願だった Raspberry Pi 4 の SDCard-less Boot ができたので手順をメモします。
おおまかな手順
おおまかには以下の手順で設定します。
- Raspberry Pi 設定
- EEPROM のアップデート
- Boot Order 書き換え
- Serial 確認
- PXE Boot 設定
- DHCP と TFTP のインストール
- tftpboot の配置
- cmdline.txt の書き換え
- 一部ファイルの書き換え
- SSD セットアップ
- Boot
Raspberry Pi 設定
Raspberry Pi が Network Boot できるように設定します。
Bootloader の書き換えが必要となります。
EEPROM のアップデート
network boot が公式から提供されています。
https://github.com/raspberrypi/rpi-eeprom/blob/master/firmware/release-notes.md#promote-2020-04-16-eeprom-release-critical
アップデートは、apt 経由で行います。
sudo apt update
sudo apt full-upgrade
sudo apt install rpi-eeprom
Boot Order を書き換えた EEPROM を焼く
EEPROM の設定を書き換えて、アップデートします。
pi@raspberrypi:~ $ cp /lib/firmware/raspberrypi/bootloader/critical/pieeprom-2020-04-16.bin pieeprom.bin
pi@raspberrypi:~ $ rpi-eeprom-config pieeprom.bin > bootconf.txt
pi@raspberrypi:~ $ cat bootconf.txt
[all]
BOOT_UART=0
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=0
DHCP_TIMEOUT=45000
DHCP_REQ_TIMEOUT=4000
TFTP_FILE_TIMEOUT=30000
TFTP_IP=
TFTP_PREFIX=0
BOOT_ORDER=0x1 # これを書き換える
SD_BOOT_MAX_RETRIES=3
NET_BOOT_MAX_RETRIES=5
[none]
FREEZE_VERSION=0
pi@raspberrypi:~ $ sed -i s/0x1/0x21/g bootconf.txt
pi@raspberrypi:~ $ cat bootconf.txt
[all]
BOOT_UART=0
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=0
DHCP_TIMEOUT=45000
DHCP_REQ_TIMEOUT=4000
TFTP_FILE_TIMEOUT=30000
TFTP_IP=
TFTP_PREFIX=0
BOOT_ORDER=0x21 # 書き換わった
SD_BOOT_MAX_RETRIES=3
NET_BOOT_MAX_RETRIES=5
[none]
FREEZE_VERSION=0
pi@raspberrypi:~ $ rpi-eeprom-config --out pieeprom-new.bin --config bootconf.txt pieeprom.bin
pi@raspberrypi:~ $ sudo rpi-eeprom-update -d -f ./pieeprom-new.bin
BCM2711 detected
*** INSTALLING ./pieeprom-new.bin ***
EEPROM update pending. Please reboot to apply the update.
pi@raspberrypi:~ $ sudo reboot
reboot が終わったら、以下のコマンドで実際の設定を確認します。
pi@raspberrypi:~ $ vcgencmd bootloader_config
[all]
BOOT_UART=0
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=0
DHCP_TIMEOUT=45000
DHCP_REQ_TIMEOUT=4000
TFTP_FILE_TIMEOUT=30000
TFTP_IP=
TFTP_PREFIX=0
BOOT_ORDER=0x21
SD_BOOT_MAX_RETRIES=3
NET_BOOT_MAX_RETRIES=5
[none]
FREEZE_VERSION=0
pi@raspberrypi:~ $
良さそう。
Serial の確認
tftpboot する際に、マシンの識別子に Serial を利用します。
Raspberry Pi の Serial が必要なので、いかで確認します。
pi@raspberrypi:~ $ cat /proc/cpuinfo |grep Serial
Serial : 100000002dff6fc0
必要なのは下8桁なので、2dff6fc0
を控えておきます。
PXE Boot 設定
PXE Boot の設定をします。
DHCP と TFTP インストール
こちらは前回の記事があるので割愛します。
https://www.takutakahashi.dev/prepare-to-create-rpi-k8s-ha-cluster-2/
/tftpboot の設定
前回の記事で TFTP で配信するファイルを /tftpboot
ディレクトリに格納するように設定しています。
/tftpboot
には、/tftpboot/[rpi serial]
のディレクトリに /boot
以下のファイルを格納します。
% kubectl exec -it dhcpd-78d9565b8b-x9zmx ls /tftpboot/2dff6fc0
COPYING.linux bootcode.bin kernel7.img
LICENCE.broadcom cmdline.txt kernel7l.img
bcm2708-rpi-b-plus.dtb config.txt kernel8.img
bcm2708-rpi-b.dtb fixup.dat overlays
bcm2708-rpi-cm.dtb fixup4.dat ssh
bcm2708-rpi-zero-w.dtb fixup4cd.dat start.elf
bcm2708-rpi-zero.dtb fixup4db.dat start4.elf
bcm2709-rpi-2-b.dtb fixup4x.dat start4cd.elf
bcm2710-rpi-2-b.dtb fixup_cd.dat start4db.elf
bcm2710-rpi-3-b-plus.dtb fixup_db.dat start4x.elf
bcm2710-rpi-3-b.dtb fixup_x.dat start_cd.elf
bcm2710-rpi-cm3.dtb issue.txt start_db.elf
bcm2711-rpi-4-b.dtb kernel.img start_x.elf
img をローカルマウントして取り出します。
雰囲気でいろいろやります。
sudo kpartx -a -v raspbian-buster.img
sudo mount /dev/mapper/loop0p1 /mnt
kubectl cp -r /mnt/* dhcpd-78d9565b8b-x9zmx:/tftpboot/2dff6fc0/
cmdline.txt を書き換える
cmdline.txt を書き換えて boot device を変えます。
SSD が /dev/sda
なので、以下のように書き換えれば大丈夫そうです。
console=serial0,115200 console=tty root=/dev/sda2 rootfstype=ext4 rootwait elevator=deadline
一部ファイルを書き換える (いらないかも)
一部ファイルをビルドしたものを差し替える必要があるそうです。
やってから、これ実は必要ないんじゃと思ったので今度入れ替えてみます。
wget https://github.com/Hexxeh/rpi-firmware/raw/master/start4.elf \
&& kubectl cp start4.elf dhcpd-78d9565b8b-x9zmx:/tftpboot/2dff6fc0/
wget https://github.com/Hexxeh/rpi-firmware/raw/master/fixup4.dat
&& kubectl cp fixup4.dat dhcpd-78d9565b8b-x9zmx:/tftpboot/2dff6fc0/
これで、TFTP Boot の準備が完了しました。
この状態で SD を抜いて電源を入れると、KP しますが、ブートプロセスが走ることを確認できます。
SSD セットアップ
SSD をセットアップします。
これは簡単で、 SD カードに raspbian を焼く要領で SSD に焼けば OK です。
Boot
BOOT!!!!!!!!!!!!
まとめ
結構大変でした。
また、serial の確認が必要なので、工夫しないと全自動化はできなそうですね。
参考
以下のサイトが大いに参考になりました。
というか NFS root を除いて全て以下のサイトの手順です。
https://hackaday.com/2019/11/11/network-booting-the-pi-4/
蛇足
DHCP のメッセージの意味を調べてみました。
以下の順でメッセージのやり取りが行われるようです。
参考: https://www.itbook.info/study/dhcp7.html
- DHCPDISCOVER (from: client) … DHCP 要求をブロードキャストする
- DHCPOFFER (from: server) … リース IP 候補を返答する
- DHCPREQUEST (from: client) … 正式に IP の lease を要求する
- DHCPACK (from: server) … リース期間やサブネットマスクなどの追加情報を返す