0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

@ebijunさんのRPI4用NetBSDイメージを使い複数パーティションを持ったUSBブートディスクを作成する

Last updated at Posted at 2022-01-17

普通にできること

「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_ROOTGB_SWAPGB_VARに各パーティションのサイズをGB単位で指定します。ディスクの残りは/homeに割り当てされます。

copy_NetBSD_image.sh
# !/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カード上に、EFInetbsd-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
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?