Raspberry Pi netbootのTFTP host directory設計

Raspberry Pi netbootのTFTP host directory設計

Raspberry Pi の network boot は、一般的な PXE の pxelinux.cfg とは違う挙動をする。

特に Pi firmware は、TFTP root 直下だけでなく board 固有の directory を探す。bootfile でサブディレクトリを指定しても、cmdline.txt が期待した場所から読まれないことがある。

このため、Pi ごとの board hash directory を TFTP root 直下に実ディレクトリとして作り、host ごとに cmdline.txt を制御する設計が扱いやすい。

本文中の 192.0.2.0/24 は説明用の documentation range である。homecluster-infra で OpenWrt 実機へ反映する場合は、router hostvars の openwrt_lan_ipaddropenwrt_dhcp_ntp_serversopenwrt_gentoo_server_host を外部 inventory で明示し、TFTP / NFS / dnsmasq の endpoint に documentation range を残さない。

目的

  • boot firmware / kernel / DTB / initramfs は release 単位で共有する
  • host ごとの config.txt / cmdline.txt は board hash directory に置く
  • NFS root の release 切替は cmdline.txt で行う
  • TFTP release の更新と host boot 先の切替を分ける

directory構成

例として、TFTP root を次のように分ける。

tftp-root/
├── dates/
│   ├── 2026-02-05/
│   │   ├── start4.elf
│   │   ├── fixup4.dat
│   │   ├── kernel8.img
│   │   ├── initramfs-pxe.img
│   │   ├── bcm2711-rpi-4-b.dtb
│   │   ├── config.txt
│   │   └── cmdline.txt
│   └── 2026-02-08/
│       └── ...
├── 1f9e9551/
│   ├── start4.elf -> ../dates/2026-02-05/start4.elf
│   ├── fixup4.dat -> ../dates/2026-02-05/fixup4.dat
│   ├── kernel8.img -> ../dates/2026-02-05/kernel8.img
│   ├── initramfs-pxe.img -> ../dates/2026-02-05/initramfs-pxe.img
│   ├── bcm2711-rpi-4-b.dtb -> ../dates/2026-02-05/bcm2711-rpi-4-b.dtb
│   ├── config.txt
│   └── cmdline.txt
└── f5ba5af1/
    └── ...

dates/<release> は boot artifact の保管場所、<board_hash>/ は Pi firmware が直接読む host directory として扱う。

実ディレクトリを使う理由

<board_hash> -> dates/<release> のような symlink だけでも成立することはある。しかし、host ごとに cmdline.txt を変えたい場合、実ディレクトリの方が安全である。

方式利点弱点
board hash を symlink にするrelease 切替が単純host 固有 cmdline.txt を置きにくい
board hash を実ディレクトリにするhost ごとの cmdline.txt / config.txt を持てるsymlink 作成対象が増える

実ディレクトリ方式では、firmware や kernel は release directory への symlink にし、cmdline.txt だけ host ごとに生成できる。

release切替の責務

release 管理は次の 2 層に分ける。

役割
release builddates/<release> に firmware / kernel / DTB / initramfs を配置する
host switch<board_hash>/cmdline.txt と symlink を更新し、その host の boot 先を変える

この分離をしておくと、「新しい release を作っただけ」なのか、「特定 host が新 release を boot するようになった」のかが明確になる。

さらに、boot artifact の release と NFS rootfs の release は別に扱える。

例えば、kernel8.img、DTB、initramfs は既存の dates/20260218 を参照したまま、host directory の cmdline.txt だけを変更し、Pi5 は /gentoo/20260525-rpi5/nfs、Pi4 は /gentoo/20260525-rpi4/nfs を見る構成にできる。この場合、kernel module は rootfs 側で boot artifact と同じ Raspberry Pi firmware commit に揃える。

この分離は、Pi4/Pi5 世代別 rootfs の canary に向いている。TFTP artifact を進める前に、NFS rootfs だけを host 単位で切り替え、/proc/cmdline、overlay root、/lib/modules、k3s Ready 状態を確認できる。

cmdline.txtの例

host directory の cmdline.txt は、NFS root の release を指定する。

console=serial0,115200 console=tty1 root=nfs4:192.0.2.10:/exports/gentoo/2026-02-05/nfs,vers=4.2,proto=tcp ip=dhcp rw rd.neednet=1 rd.overlayfs=1 rd.shell

release rollback は、host directory の symlink と cmdline.txt を前の release に戻すだけでよい。

dnsmasq側の注意

OpenWrt dnsmasq などで Raspberry Pi を netboot させる場合、host tag と boot rule の対応を明示する。

よくある注意点は次の通り。

  • dhcp-boot に渡す server name と server address は両方指定する
  • Pi が unicast DHCP OFFER を受け付けない場合は broadcast 応答を試す
  • host 固有の bootfile 指定が期待通り出力されない場合は、tag 付き dhcp-boot を明示する
  • TFTP log で Pi が実際に要求している path を見る

特に、Pi が /<board_hash>/start4.elf のような path を要求しているなら、その directory を TFTP root 直下に作るのが素直である。

観測ポイント

boot が期待した release に入っているかは、TFTP server と起動後の両方で見る。

TFTP server 側:

grep -E 'tftp|start|cmdline|kernel|initramfs' /var/log/syslog

client 側:

cat /proc/cmdline
findmnt -no TARGET,SOURCE,FSTYPE,OPTIONS /
uname -a

/proc/cmdlineroot= が期待 release を指していること、/ が overlayfs root になっていること、kernel version と module set が合っていることを確認する。

設計上の境界

TFTP host directory は boot file 選択の責務だけを持つ。

次のものは別レイヤーに分ける。

  • rootfs の生成
  • dracut initramfs の生成
  • NFS export 設定
  • post-boot configuration
  • application data の永続化

この分離により、boot 先切替の検証を短くできる。例えば、rootfs rebuild をせず、TFTP host directory の cmdline.txt だけを変えて rollback / canary boot を試せる。