takutakahashi.dev

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

  1. DHCPDISCOVER (from: client) … DHCP 要求をブロードキャストする
  2. DHCPOFFER (from: server) … リース IP 候補を返答する
  3. DHCPREQUEST (from: client) … 正式に IP の lease を要求する
  4. DHCPACK (from: server) … リース期間やサブネットマスクなどの追加情報を返す