あっきぃ日誌

鉄道ブログのような技術系ブログのようななにか

Raspberry Pi 3でPXEネットワークブート

昨日・今日と、raspberrypi.orgのブログでRaspberry Pi3のCPUの機能を利用したSDカード以外のブートについて紹介されています。いずれもベータのようですが、今日はPXEの話題がでていたのでこれはとおもい試してみました。

最近はラズピッピの話題はraspi.jpに書くようにしていますが、自宅固有の環境が出るのでこちらに書くことにしました。

raspberrypi.orgのブログの記事はこちら。

www.raspberrypi.org

昨日のはこちら→ Pi 3 booting part I: USB mass storage boot beta - Raspberry Pi

参考にする手順はブログ中にもリンクがありますが以下です。

環境

参考の手順はDHCPサーバー・NFSサーバーともにRaspberry Piを使用しているみたいですが、うちの場合はもうdnsmasqによるDHCP/DNS/PXEサーバーがVMware仮想マシンで稼働していて、NFSサーバーも同様に仮想マシンですでに存在しているので、これらを流用します。

関係ないですけど、ふつうのご家庭でもPXEインストール環境くらい整備されてますよね?

というわけでうちの環境は以下のとおりです。OSはいずれもUbuntu Server 14.04。

Raspberry Pi 3の用意

これはClient configurationの手順を読めばOKです。まあ、最新の環境にして、rpi-updateを実行するだけです。

sudo BRANCH=next rpi-update

次に/boot/config.txtにprogram_usb_boot_mode=1の1行を足して再起動。以下のコマンドを実行して実行結果が同じだったら足した1行を削除してシャットダウンします。この時点でCPU?何か書き込んでいるのか、単に確認なのかはまだ不明です。

$ vcgencmd otp_dump | grep 17:
17:3020000a
(program_usb_boot_mode=1をする前は17:1020000aらしい)

(DHCPサーバーで作業)dnsmasqの設定

参考ページではDHCPサーバーを動かすに当たってのネットワークアドレス設定も含まれているので長ったらしいですが、すでにその辺がすんでいるウチでは、設定のキモは/etc/dnsmasq.confの以下の行です。tftpの設定を足して、pxe-serviceを記述するのですが、前者も設定済みなので、追記したのは後者の1行だけとなりました。

dhcp-range=192.168.29.120,192.168.29.149,255.255.255.0,2h
enable-tftp
tftp-root=/tftpboot
pxe-service=0,"Raspberry Pi Boot"  ←追記したのはこれだけ

既存のX86のPXEは書き方を変えることで両対応にできました。

(前) dhcp-boot=install/pxelinux.0
(今) pxe-service=X86PC,"PXE", install/pxelinux

書き換えたらdnsmasqサービスを再起動します。X86PC環境でPXEブートするとこんな感じでプロンプトがでるようになります。

f:id:Akkiesoft:20160805235439p:plain

(DHCPサーバーで作業)/tftpbootにRaspberry Pi用ファイルを用意

/tftpboot以下にRaspberry Pi用のブートファイルを置きます。参考ページには「bootcode.binとstart.elfが必要」と書きつつ/bootをまるごと/tftpbootにコピーしていますが、/tftpboot直下に必要なのはbootcode.binのみで、その他のファイルはRaspberry Pi 3のCPUのシリアル番号から左の0を削った名前でディレクトリを掘って格納すれば/tftpboot以下をスッキリした状態にできます。

ちなみにラズピッピのCPUの確認は適当に起動した後cat /proc/cpuinfoを実行します。

$ cat /proc/cpuinfo
Hardware	: BCM2709
Revision	: a02082
Serial		: 0000000012345678

そして/tftpboot以下の構成。/boot以下の中身はどれを使えと言う指示がないので、先のRaspberry Pi3で用意した最新のものを利用しなくても大丈夫なはずですが、私の場合は最新のものを配置しました。

/tftpboot/install
         /12345678/start.elf
                    :
                  (bootcode.bin以外の/boot以下のファイル全部)
                    :
         /bootcode.bin

起動した後のNFSの位置を指示するのはcmdline.txtでやります。

$ sudo vi /tftpboot/12345678/cmdline.txt

root=/dev/nfs nfsroot=192.168.29.11:/3tb/rpi-netboot rw ip=dhcp rootwait elevator=deadline

(NFSサーバーで作業)NFSサーバーの設定

NFSサーバーのインストールは割愛します。/etc/exportsでエクスポート設定を書きます。

/3tb    *(rw,no_root_squash)

/3tb/rpi-netbootにはRaspbianで言うところのmmcblk0p2(/root)の中身を置きます。参考ページではサーバーにするRaspbianの中身をコピーしていましたが、ウチの場合はUbuntu Serverなので、ディスクイメージからmmcblk0p2の中身をコピーすることにしました。

手順は以下のとおりです。Raspbian Jessie LITEを利用していますが、通常版でも良いと思います。

(ディレクトリを掘る)
$ mkdir /3tb/rpi-netboot

(ディスクイメージをマウントする)
$ sudo losetup -f
/dev/loop3  ←/dev/loop3が作成される
$ sudo losetup /dev/loop3 /3tb/2016-05-27-raspbian-jessie-lite.img

(/dev/loop3p2を/mntにマウント)
$ sudo mount /dev/loop3p2 /mnt

(/mntの中身をrsyncでコピー)
$ sudo rsync -xa /mnt/ /3tb/rpi-netboot

(/mntをアンマウント)
$ sudo umount /mnt

(/dev/loop3を片付ける)
$ sudo losetup -d /dev/loop3

(片付けの確認)
$ sudo losetup -a

losetupの部分の参考ページ: イメージファイルをmountしてごにょごにょする手順 - mir the developer

コピーしたRaspbianの中身を少し書き換えます。参考ページではSSHのホスト鍵再生成をしていますが、私の手順では生成される前のディスクイメージの中身を用意したので不要です。/3tb/rpi-netboot/etc/fstabだけ編集します。

$ sudo vi /3tb/rpi-netboot/etc/fstab

proc            /proc           proc    defaults          0       0
/dev/mmcblk0p1  /boot           vfat    defaults          0       2 ←この行を消す
/dev/mmcblk0p2  /               ext4    defaults,noatime  0       1 ←この行を消す

起動してみる

以上で作業はおわりなので、Raspberry Pi 3のネットワークブートを試してみます。Raspberry Pi 3からSDカードを抜いて、LANケーブルだけ挿した状態から電源を投入します。

DHCPサーバーでdnsmasqのログを見ながらブートの様子を見守ってみましょう。

$ tail -f /var/log/syslog

Aug  5 23:34:39 miku dnsmasq-dhcp[24705]: 653460281 available DHCP range: 192.168.29.120 -- 192.168.29.149
Aug  5 23:34:39 miku dnsmasq-dhcp[24705]: 653460281 vendor class: PXEClient:Arch:00000:UNDI:002001
Aug  5 23:34:39 miku dnsmasq-dhcp[24705]: 653460281 DHCPDISCOVER(eth0) b8:27:eb:xx:xx:xx 
Aug  5 23:34:39 miku dnsmasq-dhcp[24705]: 653460281 tags: known, eth0
Aug  5 23:34:39 miku dnsmasq-dhcp[24705]: 653460281 DHCPOFFER(eth0) 192.168.29.83 b8:27:eb:xx:xx:xx 
Aug  5 23:34:39 miku dnsmasq-dhcp[24705]: 653460281 requested options: 43:vendor-encap, 60:vendor-class, 67:bootfile-name, 
Aug  5 23:34:39 miku dnsmasq-dhcp[24705]: 653460281 requested options: 128, 129, 130, 131, 132, 133, 134, 135, 66:tftp-server
Aug  5 23:34:39 miku dnsmasq-dhcp[24705]: 653460281 next server: 192.168.29.39
Aug  5 23:34:39 miku dnsmasq-dhcp[24705]: 653460281 sent size:  1 option: 53 message-type  2
Aug  5 23:34:39 miku dnsmasq-dhcp[24705]: 653460281 sent size:  4 option: 54 server-identifier  192.168.29.39
Aug  5 23:34:39 miku dnsmasq-dhcp[24705]: 653460281 sent size:  4 option: 51 lease-time  infinite
Aug  5 23:34:39 miku dnsmasq-dhcp[24705]: 653460281 sent size:  4 option:  1 netmask  255.255.255.0
Aug  5 23:34:39 miku dnsmasq-dhcp[24705]: 653460281 sent size:  4 option: 28 broadcast  192.168.29.255
Aug  5 23:34:39 miku dnsmasq-dhcp[24705]: 653460281 sent size:  9 option: 60 vendor-class  50:58:45:43:6c:69:65:6e:74
Aug  5 23:34:39 miku dnsmasq-dhcp[24705]: 653460281 sent size: 17 option: 97 client-machine-id  00:44:44:44:44:44:44:44:44:44:44:44:44:44...
Aug  5 23:34:39 miku dnsmasq-dhcp[24705]: 653460281 sent size: 47 option: 43 vendor-encap  06:01:03:0a:04:ff:50:58:45:08:07:80:00:01...
Aug  5 23:34:44 miku dnsmasq-tftp[24705]: sent /tftpboot/bootcode.bin to 192.168.29.83
Aug  5 23:34:44 miku dnsmasq-tftp[24705]: file /tftpboot/bootsig.bin not found
Aug  5 23:34:44 miku dnsmasq-tftp[24705]: file /tftpboot/83ca2283/autoboot.txt not found
Aug  5 23:34:44 miku dnsmasq-tftp[24705]: error 0 Early terminate received from 192.168.29.83
Aug  5 23:34:44 miku dnsmasq-tftp[24705]: failed sending /tftpboot/83ca2283/start.elf to 192.168.29.83
Aug  5 23:34:44 miku dnsmasq-tftp[24705]: sent /tftpboot/83ca2283/config.txt to 192.168.29.83
Aug  5 23:34:44 miku dnsmasq-tftp[24705]: file /tftpboot/83ca2283/recovery.elf not found
Aug  5 23:34:45 miku dnsmasq-tftp[24705]: sent /tftpboot/83ca2283/start.elf to 192.168.29.83
Aug  5 23:34:45 miku dnsmasq-tftp[24705]: sent /tftpboot/83ca2283/fixup.dat to 192.168.29.83
Aug  5 23:34:46 miku dnsmasq-tftp[24705]: file /tftpboot/83ca2283/recovery.elf not found
Aug  5 23:34:46 miku dnsmasq-tftp[24705]: sent /tftpboot/83ca2283/config.txt to 192.168.29.83
Aug  5 23:34:46 miku dnsmasq-tftp[24705]: file /tftpboot/83ca2283/dt-blob.bin not found
Aug  5 23:34:46 miku dnsmasq-tftp[24705]: file /tftpboot/83ca2283/recovery.elf not found
Aug  5 23:34:46 miku dnsmasq-tftp[24705]: sent /tftpboot/83ca2283/config.txt to 192.168.29.83
Aug  5 23:34:46 miku dnsmasq-tftp[24705]: file /tftpboot/83ca2283/bootcfg.txt not found
Aug  5 23:34:46 miku dnsmasq-tftp[24705]: sent /tftpboot/83ca2283/cmdline.txt to 192.168.29.83
Aug  5 23:34:46 miku dnsmasq-tftp[24705]: file /tftpboot/83ca2283/recovery8.img not found
Aug  5 23:34:46 miku dnsmasq-tftp[24705]: file /tftpboot/83ca2283/recovery8-32.img not found
Aug  5 23:34:46 miku dnsmasq-tftp[24705]: file /tftpboot/83ca2283/recovery7.img not found
Aug  5 23:34:46 miku dnsmasq-tftp[24705]: file /tftpboot/83ca2283/recovery.img not found
Aug  5 23:34:46 miku dnsmasq-tftp[24705]: file /tftpboot/83ca2283/kernel8.img not found
Aug  5 23:34:46 miku dnsmasq-tftp[24705]: file /tftpboot/83ca2283/kernel8-32.img not found
Aug  5 23:34:46 miku dnsmasq-tftp[24705]: file /tftpboot/83ca2283/armstub8.bin not found
Aug  5 23:34:46 miku dnsmasq-tftp[24705]: error 0 Early terminate received from 192.168.29.83
Aug  5 23:34:46 miku dnsmasq-tftp[24705]: failed sending /tftpboot/83ca2283/kernel7.img to 192.168.29.83
Aug  5 23:34:46 miku dnsmasq-tftp[24705]: file /tftpboot/83ca2283/armstub8-32.bin not found
Aug  5 23:34:46 miku dnsmasq-tftp[24705]: file /tftpboot/83ca2283/armstub7.bin not found
Aug  5 23:34:46 miku dnsmasq-tftp[24705]: file /tftpboot/83ca2283/armstub.bin not found
Aug  5 23:34:48 miku dnsmasq-tftp[24705]: sent /tftpboot/83ca2283/kernel7.img to 192.168.29.83
Aug  5 23:34:48 miku dnsmasq-tftp[24705]: sent /tftpboot/83ca2283/bcm2710-rpi-3-b.dtb to 192.168.29.83
Aug  5 23:34:48 miku dnsmasq-tftp[24705]: sent /tftpboot/83ca2283/config.txt to 192.168.29.83

一通り転送が終わると、Raspberry Pi 3からいつものRaspbianのブート画面が表示されます。

まとめ

ベータとは言いつつもとくに問題なくPXEブートができました。

コンピューター教室とかのような、作っては壊し…みたいな環境では、一度作りこんでしまえばセットアップの手間がだいぶ削減できそうな気がします。使い終えたらNFSサーバーに置いたファイルをもとに戻すだけですし(/bootは書き換えできないのでそのまま)。

なんかこれはちょっと使えそうですね〜。

追記

空のMicroSDカードを刺して起動してもPXEブートしました。しかも起動したRaspbianから普通に見えて、マウントして読み書きもイケるっぽいです。なるほどね。