Raspberry Pi netbootのTFTP host directory設計
Posted:
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_ipaddr、openwrt_dhcp_ntp_servers、openwrt_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 build | dates/<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/cmdline の root= が期待 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 を試せる。