普通にできること
「Raspberry Pi 4」(以下、RPI4)で、SDカードではなくHDDやSDD等のUSBディスクからブート可能になりました。
今回は、2.5インチのHDD/SSDをUSB3.0で接続するJMS578ベースの透明ケースと、USBバスパワー機器へ安定した電力を供給するためのACアダプターを使って、 HDDをRPI4へ接続します。
@ebijunさんのディスクイメージ(RPI4用はYYYY-MM-DD-aarch64ディレクトリ)を、USBディスク上で展開すれば、RPI4からUSBブートできます。このディスクイメージはGPT形式で、ブートマネージャを格納したEFIパーティションと、NetBSDのルートファイルシステムのためのffsパーティションの2つの区画に区切られています。
以下は、Macを使った作業手順です。
/dev/disk4
は、USB接続した750GBの空のHDDです。
Darwin$ diskutil list /dev/disk4
/dev/disk4 (external, physical):
#: TYPE NAME SIZE IDENTIFIER
0: *750.2 GB disk4
Darwin$ sudo gpt -r show -l /dev/rdisk4
start size index contents
0 1465149168
HDDにディスクイメージを転送します。
Darwin$ sudo dd if=./2021-12-06-netbsd-raspi-aarch64.img of=/dev/rdisk4 bs=1m
2399+1 records in
2399+1 records out
2516581376 bytes transferred in 25.905331 secs (97145308 bytes/sec)
Darwin$ diskutil list /dev/disk4
/dev/disk4 (external, physical):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *750.2 GB disk4
1: EFI NO NAME 83.9 MB disk4s1
2: 49F48D5A-B10E-11DC-B99B-0019D1879648 2.4 GB disk4s2
Darwin$ sudo gpt -r show -l /dev/disk4
start size index contents
0 1 PMBR
1 1 Pri GPT header
2 1 Pri GPT table
3 163840 1 GPT part - "EFI"
163843 4751355 2 GPT part - "netbsd-root"
4915198 1460233970
このHDDをSDカードを抜いたRPI4にUSB接続して電源投入すればokです。SDカードからブートした場合と同様に、ルートパーティションがディスク容量にあわせたサイズに自動調整され、その後ログイン可能となります。
追加パーティションを定義しようとしたらダメだった
このまま使い続けることもできたのですが、swap領域も作りたいですし、/home
や/var
も分離したいです。
そこで、「普通にできること」の手順で作成したディスクをRPI4でブートする前に、USBディスクに追加のパーティションを設定することにしました。
パーティションを追加しようとしたところ、セカンダリヘッダがないのでエラーとなりました。
そこで、エラーメッセージの指示に従いリカバリーしました。
Darwin$ sudo gpt add -t 49F48D5A-B10E-11DC-B99B-0019D1879648 /dev/disk4
gpt add: /dev/disk4: error: no secondary GPT header; run recover
Darwin$ sudo gpt recover /dev/disk4
gpt recover: /dev/disk4: recovered secondary GPT table from primary
gpt recover: /dev/disk4: recovered secondary GPT header from primary
Darwin$ sudo gpt -r show -l /dev/disk4
start size index contents
0 1 PMBR
1 1 Pri GPT header
2 1 Pri GPT table
3 163840 1 GPT part - "EFI"
163843 4751355 2 GPT part - "netbsd-root"
4915198 1460233968
1465149166 1 Sec GPT table
1465149167 1 Sec GPT header
パーティション追加に再挑戦します。
Darwin$ sudo gpt add -t 49F48D5A-B10E-11DC-B99B-0019D1879648 /dev/disk4
gpt add: /dev/disk4: error: no available table entries
GPTテーブルに2つしかパーティションを定義出来ないのはなぜか?
gpt show
コマンドの出力を眺めていて、GPTテーブルのサイズが1セクタしかないことに気づきました。
@ebijunさんのディスクイメージ作成用スクリプトを見てみると、その理由は94行目にありました。
gpt create -p 2 ${VND}
ここで、最大パーティション数を2としているので、3つ目のパーティションを追加しようとしてエラーになったのでした。
NetBSD版のgpt header
コマンドを使えばGPTヘッダの内容を観ることが出来ます。確かに、GPTエントリの最大数が2となっています。
arm64# gpt header sd0
Media Size: 750156374016 (699G)
Sector Size: 512
Number of Sectors: 1465149168 (1G)
Header Information:
- GPT Header Revision: 1.0
- First Data Sector: 3 (3B)
- Last Data Sector: 4915197 (5M)
- Media GUID: a852220f-8bb8-4918-bb6c-7f504de26c28
- Number of GPT Entries: 2
解決策:HDD上にGPTを作成し直してイメージファイルからパーティション毎にデータを転送する
まず、作業用Mac上で、ディスクイメージファイルをアタッチします。この例では、/dev/disk5
が割り当てられました。
Darwin$ hdiutil attach -nomount ./2021-12-06-netbsd-raspi-aarch64.img
/dev/disk5 GUID_partition_scheme
/dev/disk5s1 EFI
/dev/disk5s2 49F48D5A-B10E-11DC-B99B-0019D18
Darwin$ diskutil list /dev/disk5
/dev/disk5 (disk image):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme +2.5 GB disk5
1: EFI NO NAME 83.9 MB disk5s1
2: 49F48D5A-B10E-11DC-B99B-0019D1879648 2.4 GB disk5s2
Darwin$ gpt -r show -l /dev/disk5
start size index contents
0 1 PMBR
1 1 Pri GPT header
2 1 Pri GPT table
3 163840 1 GPT part - "EFI"
163843 4751355 2 GPT part - "netbsd-root"
GPT作成とデータ転送の部分はスクリプトを書きました。DEV_IMG
にイメージファイルをアタッチしたデバイス名を、DEV_TGT
に宛先USBディスクのデバイス名を、GB_ROOT
、GB_SWAP
、GB_VAR
に各パーティションのサイズをGB単位で指定します。ディスクの残りは/home
に割り当てされます。
# !/bin/sh
DEV_IMG=/dev/disk5
DEV_TGT=/dev/disk4
GB_ROOT=8
GB_SWAP=8
GB_VAR=1
SIZE_BOOT=`gpt -r show -l $DEV_IMG | grep EFI | tr -s ' ' | cut -d ' ' -f 3`
SIZE_ROOT=`expr 2 \* 1024 \* 1024 \* $GB_ROOT`
SIZE_SWAP=`expr 2 \* 1024 \* 1024 \* $GB_SWAP`
SIZE_VAR=`expr 2 \* 1024 \* 1024 \* $GB_VAR`
RDEV_TGT=`echo $DEV_TGT | sed s:^/dev/disk:/dev/rdisk:`
UUID_FFS="49F48D5A-B10E-11DC-B99B-0019D1879648"
UUID_SWAP="49F48D32-B10E-11DC-B99B-0019D1879648"
sudo gpt destroy $DEV_TGT > /dev/null 2>&1
sudo dd if=/dev/zero of=$RDEV_TGT count=1
sudo gpt create $DEV_TGT
sudo gpt add -s $SIZE_BOOT -t efi $DEV_TGT
sudo gpt label -i 1 -l EFI $DEV_TGT
sudo gpt add -s $SIZE_ROOT -t $UUID_FFS $DEV_TGT
sudo gpt label -i 2 -l netbsd-root $DEV_TGT
sudo gpt add -s $SIZE_SWAP -t $UUID_SWAP $DEV_TGT
sudo gpt label -i 3 -l swap $DEV_TGT
sudo gpt add -s $SIZE_VAR -t $UUID_FFS $DEV_TGT
sudo gpt label -i 4 -l var $DEV_TGT
sudo gpt add -t $UUID_FFS $DEV_TGT
sudo gpt label -i 5 -l home $DEV_TGT
sudo dd if=${DEV_IMG}s1 of=${DEV_TGT}s1 bs=1m
sudo dd if=${DEV_IMG}s2 of=${DEV_TGT}s2 bs=1m
スクリプトの実行結果は、こんな感じです。
Darwin$ sh copy_NetBSD_image.sh
Password:
1+0 records in
1+0 records out
512 bytes transferred in 0.001383 secs (370256 bytes/sec)
/dev/disk4s1 added
/dev/disk4s1 labeled
/dev/disk4s2 added
/dev/disk4s2 labeled
/dev/disk4s3 added
/dev/disk4s3 labeled
/dev/disk4s4 added
/dev/disk4s4 labeled
/dev/disk4s5 added
/dev/disk4s5 labeled
80+0 records in
80+0 records out
83886080 bytes transferred in 4.695826 secs (17863967 bytes/sec)
2319+1 records in
2319+1 records out
2432693760 bytes transferred in 153.070320 secs (15892655 bytes/sec)
出来上がったUSB起動ディスクをRPI4に接続してブートしてから、追加パーティションへのファイルシステム準備や/etc/fstab
の編集を行なっても良いです。既に稼働中の他のNetBSDシステムがあれば、もっと楽に作業出来ます。
まず、USB起動ディスクをNetBSDシステムへ接続します。
[ 73801.522527] sd0: GPT GUID: e24dd8c0-fd6b-48c0-a548-8dcd07feb70e
[ 73801.522527] dk2 at sd0: "abdb225f-f796-43b8-8c59-ad2171c6dcf2", 163840 blocks at 34, type: msdos
[ 73801.522527] autoconfiguration error: sd0: wedge named 'EFI' already existed, using 'abdb225f-f796-43b8-8c59-ad2171c6dcf2'
[ 73801.522527] dk3 at sd0: "7c4b78ae-efa1-4416-958a-2dd3ee6a15e7", 16777216 blocks at 163874, type: ffs
[ 73801.522527] autoconfiguration error: sd0: wedge named 'netbsd-root' already existed, using '7c4b78ae-efa1-4416-958a-2dd3ee6a15e7'
[ 73801.522527] dk4 at sd0: "swap", 16777216 blocks at 16941090, type: swap
[ 73801.522527] dk5 at sd0: "var", 2097152 blocks at 33718306, type: ffs
[ 73801.522527] dk6 at sd0: "home", 1429333677 blocks at 35815458, type: ffs
この例では、SDカードから起動したNetBSDシステムにUSB起動ディスクを接続しました。
SDカード上に、EFI
とnetbsd-root
という名前のパーティションが既に存在するためにエラーメッセージが出力されていますが、気にしなくて良いです。
/var
と/home
に使うためのパーティションをフォーマットしましょう。
arm64# newfs /dev/dk5
/dev/rdk5: 1024.0MB (2097152 sectors) block size 16384, fragment size 2048
using 6 cylinder groups of 170.67MB, 10923 blks, 21504 inodes.
super-block backups (for fsck_ffs -b #) at:
32, 349568, 699104, 1048640, 1398176, 1747712,
arm64# newfs /dev/dk6
/dev/rdk6: 697916.8MB (1429333672 sectors) block size 32768, fragment size 4096
using 942 cylinder groups of 740.91MB, 23709 blks, 47104 inodes.
super-block backups (for fsck_ffs -b #) at:
64, 1517440, 3034816, 4552192, 6069568, 7586944, 9104320, 10621696, 12139072,
...............................................................................
USB起動ディスクのルートファイルシステムをマウントして/etc/fstab
を編集します。
arm64# mount /dev/dk3 /mnt
arm64# vi /mnt/etc/fstab
arm64# cat /mnt/etc/fstab
# NetBSD /etc/fstab
# See /usr/share/examples/fstab/ for more examples.
NAME=netbsd-root / ffs rw,noatime 1 1
NAME=EFI /boot msdos rw 1 1
ptyfs /dev/pts ptyfs rw
procfs /proc procfs rw
tmpfs /var/shm tmpfs rw,-m1777,-sram%25
NAME=swap none swap sw,dp 0 0
NAME=var /var ffs rw 1 2
NAME=home /home ffs rw 1 2
NAME=swap /tmp mfs rw,-s=132048
/home
のマウントポイントを作成し、/var
以下も移しておきます(マウントポイント/mnt2
がなければ作って下さい)。
arm64# mkdir /mnt/home
arm64# mount /dev/dk5 /mnt2
arm64# mv /mnt/var /mnt/var.old
arm64# mkdir /mnt/var
arm64# cd /mnt/var.old; tar cf - . | (cd /mnt2; tar xf -)
toor
アカウントでsshできるように証明書もコピーしておきましょう。
arm64# cp -pr /root/.ssh /mnt/root
完了
出来上がったUSBディスクでRPI4からブートします。作業完了です。お疲れ様でした。
arm64# dkctl sd0 listwedges
/dev/rsd0: 5 wedges:
dk0: EFI, 163840 blocks at 34, type: msdos
dk1: netbsd-root, 16777216 blocks at 163874, type: ffs
dk2: swap, 16777216 blocks at 16941090, type: swap
dk3: var, 2097152 blocks at 33718306, type: ffs
dk4: home, 1429333677 blocks at 35815458, type: ffs
rm64# df
Filesystem 1K-blocks Used Avail %Cap Mounted on
/dev/dk1 8160101 2163136 5588960 27% /
/dev/dk3 1032238 48314 932314 4% /var
/dev/dk0 81820 23228 58592 28% /boot
ptyfs 1 1 0 100% /dev/pts
procfs 4 4 0 100% /proc
tmpfs 1005228 0 1005228 0% /var/shm
/dev/dk4 709060004 4 673607000 0% /home
mfs:1086 63927 1 60730 0% /tmp