やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

Raspberry Pi 4B SDブート+USBルート(≒USB boot)に成功

 Pi3B初期のときにやったアレ。超大変。

モチベ

 SDカードだといずれ書込上限で使えなくなってしまう。そこでUSB接続したHDDで代用したい。

情報源

 ブートはSDカード、それ以外の諸々はHDDに保存する。

 この方法、Pi3B初期の頃にやっていたアレでは? 同じ方法でできるのかも。

方法

3Bのときのアレ

 フォーラムにはスクリプトを書いてくれた人もいるみたい。

 でもディスク操作は怖いので自分の手でやりたい。

事前準備

ハード

 必要なものは以下。

  • PC(Pi3B+)
  • HDD (今回は 2.5 inch 1TB を使用。内容を全消去していいもの)
  • HDDケース (USB接続するヤツ)
  • USBハブ(セルフパワー)
  • micro SDカード(8GB以上。Raspbian Buster入り)

 Pi3B+で2台以上外付HDDをUSB接続して使うときは、セルフパワーUSBハブを介すること。さもなくば低電圧でフリーズすると思われる。

 1台までなら大丈夫だが、2台目以降はセルフパワーにしたほうがいいと思う。今回のPi3B+はUSB bootでHDDを使っており、すでにPi3B+から電源供給を受けている。さらに2台目としてPi4Bのルート用HDDを接続する予定のため、これをセルフパワーUSBハブ経由にする。

ソフト

 Raspbian Busterをインストールした初回ブート済みのSDカードを用意する。

手順

 3Bのときの以下の手順をそのままマネしてやってみる。

 ざっくり言うと以下。

  1. Pi3B+を起動する
  2. HDDをパーティション分けする
  3. HDDにRaspbian Busterのrootパーティションにある内容を書込む
  4. ブートパーティションを指定する
  5. Pi4BにSDカード+HDDを装着してブートすることを確認

 手順5までPi4B不要。他のマシンでHDDを作成する。ここではPi3B+を使う。

1. Pi3B+を起動する

 低電圧にならぬようUSBハブ電源を先に投入する

  1. USBハブ電源をACに挿す
  2. Pi3B+電源をACに挿す
  3. Pi3B+が起動する

 もしブートしないなら、HDDは起動後に挿す。

2. HDDをパーティション分けする

  1. デバイスIDを調べる
  2. パーティション分けする

2-1. デバイスIDを調べる

 まずはHDDのデバイスIDを調べる。方法はいくつかある。ターミナルにて以下コマンドを実行する。

  • sudo fdisk -l
  • df -h

 デバイスIDは接続状況によって異なる。今回は以下のようになった。

$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/root        917G   30G  850G    4% /
...
/dev/sda1         44M   23M   21M   52% /boot
...
$ fdisk -l
fdisk: cannot open /dev/ram0: 許可がありません
fdisk: cannot open /dev/ram1: 許可がありません
fdisk: cannot open /dev/ram2: 許可がありません
fdisk: cannot open /dev/ram3: 許可がありません
fdisk: cannot open /dev/ram4: 許可がありません
fdisk: cannot open /dev/ram5: 許可がありません
fdisk: cannot open /dev/ram6: 許可がありません
fdisk: cannot open /dev/ram7: 許可がありません
fdisk: cannot open /dev/ram8: 許可がありません
fdisk: cannot open /dev/ram9: 許可がありません
fdisk: cannot open /dev/ram10: 許可がありません
fdisk: cannot open /dev/ram11: 許可がありません
fdisk: cannot open /dev/ram12: 許可がありません
fdisk: cannot open /dev/ram13: 許可がありません
fdisk: cannot open /dev/ram14: 許可がありません
fdisk: cannot open /dev/ram15: 許可がありません
fdisk: cannot open /dev/sda: 許可がありません
fdisk: cannot open /dev/sdb: 許可がありません

 Pi3B+はUSB bootしている。マウント位置/bootにあたるデバイスIDは/dev/sda1である。もしこれを間違って削除してしまえば、今のシステムやデータを全消去してしまう。

 本来USBを挿せば自動マウントするはずだが、私の環境ではマウントしなかった。マウントすればdf -hにも表示されるはずだが、出ていない。

 fdisk -lコマンドにて/dev/sdbが見つかる。これが今回Raspbian Busterの/boot領域以外を保存したいHDDであろう。sudoをつければ正しく実行され、詳しいパーティションまで表示される。以下のように。

$ sudo fdisk -l
...
Disk /dev/sdb: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x7dfbf427

Device     Boot      Start        End    Sectors   Size Id Type
/dev/sdb1  *            63  195312562  195312500  93.1G 83 Linux
/dev/sdb2        195312563  390626163  195313601  93.1G 83 Linux
/dev/sdb3        390626225 1605479151 1214852927 579.3G  f W95 Ext'd (LBA)
/dev/sdb5        390626227 1367189827  976563601 465.7G 83 Linux
/dev/sdb6       1367189829 1429691551   62501723  29.8G 82 Linux swap / Solaris
/dev/sdb7       1429691553 1441411165   11719613   5.6G 83 Linux
/dev/sdb8       1441411167 1464850619   23439453  11.2G 83 Linux
/dev/sdb9       1464850621 1511727479   46876859  22.4G 83 Linux
/dev/sdb10      1511727481 1605479151   93751671  44.7G 83 Linux

 サイズがほぼ1TB。どのデバイスか判断するヒントとなる。パーティション分けも見られる。自分でパーティション分けしたはずだが、覚えていない。おそらくLinuxMintが入っている。

ディスクのデータ閲覧

ディスクのデータ閲覧

 ファイルの中身まで確認したい。上記パーティションのサイズから察するに、/dev/sdb3/dev/sdb5のいずれかに主なデータが入っているはず。

mount /dev/sdb5 /tmp/mnt/sdb5

 あとはファイルマネージャで/tmp/mnt/sdb5の中身を確認する。バックアップしたいデータがあれば、好きなようにする。

 終わったら以下コマンドでアンマウントする。

umount /tmp/mnt/sdb5

2-2. パーティション分けする

 デバイスIDはよく確認すること。今回は/dev/sdbとする。

sudo parted /dev/sdb

 以下のような待受になる。

(parted) 

 以降は以下の手順に従う。

  1. 既存パーティション削除
  2. 新規パーティション作成
  3. パーティション初期化

2-2-1. 既存パーティション削除

 パーティションが既存なら削除する。

(parted) p                                                                
Model: TO Exter nal USB 3.0 (scsi)
Disk /dev/sdb: 1000GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags: 

Number  Start   End    Size    Type      File system     Flags
 1      32.3kB  100GB  100GB   primary   ext4            boot
 2      100GB   200GB  100GB   primary   ext4
 3      200GB   822GB  622GB   extended                  lba
 5      200GB   700GB  500GB   logical   ext4
 6      700GB   732GB  32.0GB  logical   linux-swap(v1)
 7      732GB   738GB  6000MB  logical   ext4
 8      738GB   750GB  12.0GB  logical   ext4
 9      750GB   774GB  24.0GB  logical   ext4
10      774GB   822GB  48.0GB  logical   ext4

 以下のようにパーティション番号を指定してすべて削除する

(parted) rm 1  

2-2-2. 新規パーティション作成

位置 用途 補足
0..256MiB ブート領域 もしUSB bootに対応したらここに/bootを配置する予定
256MiB..100% ルート領域 今回はここに/boot以外を保存する

 ブート領域はFAT32形式にすること。それ以外はext4

mktable msdos
mkpart primary fat32 0MiB 256MiB
mkpart primary ext4 256MiB 100%

 途中でYes/NoやIgnore/Cancelのような選択肢が出ることがある。そのときは頭文字y,n,i,cを入力してEnterキー押下することで決定できる。y, iを選択すればいいと思う。

(parted) p  
Model: TO Exter nal USB 3.0 (scsi)
Disk /dev/sdb: 1000GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags: 

Number  Start  End     Size    Type     File system  Flags
 1      512B   268MB   268MB   primary               lba
 2      268MB  1000GB  1000GB  primary  ext4         lba

 partedを終了する。

(parted) q

2-2-3. パーティション初期化

time sudo mkfs.vfat -n BOOT -F 32 /dev/sdb1
time sudo mkfs.ext4 /dev/sdb2

 しばらく待機。35分かかった……。

3. HDDにRaspbian Busterのrootパーティションにある内容を書込む

  1. SDカード挿入する
  2. コピーする

3-1. SDカード挿入する

 Buster入りのSDカードをUSBハブに挿入する。自動マウントしてくれた。以下コマンドでデバイスIDを確認する。

df -h
...
/dev/sdc2         29G  2.8G   25G   11% /media/pi/rootfs
/dev/sdc1        253M   53M  200M   21% /media/pi/boot

 デバイスIDを整理すると以下。

バイス ID 用途
SDカード /dev/sdc ブート(/boot領域)
HDD /dev/sdb ルート(/boot以外の全領域)

3-2. コピーする

 SDカードの/rootfsをHDDへコピーする。

sudo mkdir -p /mnt/target
sudo mount /dev/sdb2 /mnt/target/
sudo mkdir -p /mnt/target/boot
sudo mount /dev/sdb1 /mnt/target/boot/
time sudo rsync -ax --progress /media/pi/rootfs /media/pi/boot /mnt/target

 2時間以上かけたのにエラーで終了。

...
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1196) [sender=3.1.2]

real    137m56.028s
user    1m12.327s
sys 2m29.636s

 しかもパスがおかしい。/mnt/target/rootfsが作られてしまった。rootfsは不要。その配下が欲しかった。

 以下でファイルマネージャを起動する。

sudo pcmanfm /mnt/target
  1. /mnt/target/rootfs配下にあるディレクトリをboot以外すべて切り取る
  2. /mnt/targetへペースト(移動)する
  3. /mnt/target/rootfsディレクトリを削除する

 以上。エラーが気になるが進める。結論からいえば起動できた。

 デバイスとマウント位置の対応表。

バイス ID マウント位置 内容
SD /dev/sdc1 /media/pi/boot Raspbian Buster ブート領域
SD /dev/sdc2 /media/pi/rootfs Raspbian Buster ルート領域
HDD /dev/sdb1 /mnt/target/boot/ 今回コピー先(将来USB bootに対応したら使えるはず)
HDD /dev/sdb2 /mnt/target 今回コピー先(ルート領域)
バイス領域
BootRoot
SD/media/pi/boot/media/pi/rootfs
HDD/mnt/target/boot/mnt/target

 だいぶややこしい。

 これでHDDに/boot以外のシステムデータを書き込めた。次はブート時に他のデータをHDDから読み取るように設定する。

 今回、HDDに/bootも書き込んだ。しかしUSB boot未対応のためブートしない。将来対応したときのために予め書き込んだだけ。あくまでブートはSDカードにある/bootを読み込む。

4. ブートパーティションを指定する

  1. デバイスのPartUuidを確認する
  2. /boot/cmdline.txt
  3. /etc/fstab

4-1. デバイスのPartUuidを確認する

ls -l /dev/disk/by-partuuid/
合計 0
lrwxrwxrwx 1 root root 10 123 22:18 AAAAAAA-01 -> ../../sda1
lrwxrwxrwx 1 root root 10 123 22:18 AAAAAAA-02 -> ../../sda2
lrwxrwxrwx 1 root root 10 124 09:47 CCCCCC-01 -> ../../sdc1
lrwxrwxrwx 1 root root 10 124 09:47 CCCCCC-02 -> ../../sdc2
lrwxrwxrwx 1 root root 10 124 10:06 BBBBBBB-01 -> ../../sdb1
lrwxrwxrwx 1 root root 10 124 10:42 BBBBBBB-02 -> ../../sdb2

 対応表は以下。

バイス ID PartUuid マウント位置 内容
SD /dev/sdc1 CCCCCC-01 /media/pi/boot Raspbian Buster ブート領域
SD /dev/sdc2 CCCCCC-02 /media/pi/rootfs Raspbian Buster ルート領域
HDD /dev/sdb1 BBBBBBB-01 /mnt/target/boot/ 今回コピー先(将来USB bootに対応したら使えるはず)
HDD /dev/sdb2 BBBBBBB-02 /mnt/target 今回コピー先(ルート領域)

4-2. /boot/cmdline.txt

 たぶんSDカードとHDD、どちらも同様に修正すべきと思われる。パスは以下。

デフォルト SD HDD
/boot/cmdline.txt /media/pi/boot/cmdline.txt /mnt/target/boot/cmdline.txt
/etc/fstab /media/pi/rootfs/etc/fstab /mnt/target/etc/fstab

SD

/media/pi/boot/cmdline.txt

HDD

/mnt/target/boot/cmdline.txt

 任意テキストエディタで内容を表示すると以下。

console=serial0,115200 console=tty1 root=PARTUUID=CCCCCC-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles

 このうち以下の箇所を変更する。

before

root=PARTUUID=CCCCCC-02

after

root=PARTUUID=BBBBBBB-02

 rootはSDカードでなくHDDにおける2番目のパーティションを読み込むようにする。

4-3. /etc/fstab

 同じくrootをSDカードからHDDにおける2番目のパーティションに変更する。パスは以下。

デフォルト SD HDD
/boot/cmdline.txt /media/pi/boot/cmdline.txt /mnt/target/boot/cmdline.txt
/etc/fstab /media/pi/rootfs/etc/fstab /mnt/target/etc/fstab

SD

sudo leafpad /media/pi/rootfs/etc/fstab

HDD

sudo leafpad /mnt/target/etc/fstab

before

proc            /proc           proc    defaults          0       0
PARTUUID=CCCCCC-01  /boot           vfat    defaults          0       2
PARTUUID=CCCCCC-02  /               ext4    defaults,noatime  0       1

after

proc            /proc           proc    defaults          0       0
PARTUUID=CCCCCC-01  /boot           vfat    defaults          0       2
PARTUUID=BBBBBBB-02  /               ext4    defaults,noatime  0       1

 /bootはそのままSDカードを指す。/だけHDDを指すよう変更する。

5. Pi4BにSDカード+HDDを装着してブートすることを確認

  1. 外す
  2. 付ける
  3. Pi4B起動

5-1. 外す

 Pi3B+からSDとHDDを外す。

 デバイスIDを調べる。

df -h
/dev/sdc2         29G  2.8G   25G   11% /media/pi/rootfs
/dev/sdc1        253M   53M  200M   21% /media/pi/boot
/dev/sdb2        916G  3.4G  866G    1% /mnt/target
/dev/sdb1        253M   53M  200M   21% /mnt/target/boot

 アンマウントする。(あれ、なんでコピー先のほうはサイズが大きいの? 2.8G→3.4G)

umount /media/pi/rootfs
umount /media/pi/boot
sudo umount /mnt/target
sudo umount /mnt/target/boot

 以下のようにエラーが出たのでsudoつけたり何回か実行した。

umount failed: 許可されていない操作です

 アンマウントできていたら以下のように出るはず。なぜかメッセージがちょっと違うパターンが色々混ざってた。

not mounted
mountpoint not found
そのようなファイルやディレクトリはありません

 あとは物理的に外すだけ。まちがってPi3B+の電源を抜かないように注意。

5-2. 付ける

 SDとHDDをPi4Bにつける。

5-3. Pi4B起動

 数分待つ。起動すればOK。

 デバイス確認。

$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/root        916G  3.4G  866G    1% /
devtmpfs         1.7G     0  1.7G    0% /dev
tmpfs            1.9G     0  1.9G    0% /dev/shm
tmpfs            1.9G   17M  1.9G    1% /run
tmpfs            5.0M  4.0K  5.0M    1% /run/lock
tmpfs            1.9G     0  1.9G    0% /sys/fs/cgroup
/dev/mmcblk0p1   253M   52M  201M   21% /boot
tmpfs            373M     0  373M    0% /run/user/1000

 /dev/rootのサイズが916Gとほぼ1TBになっている。SDカードでなくHDDである証。成功!

 ただ、Pi3B+からVNC Viewerで表示できない……。早くデスクトップ画面みたいのに。次回、解決する。

VNCで表示できなかったログ。

  1. Pi4BのIPアドレスを調べる
    • Wi-Fi親機の設定画面にログインして DHCPサーバ設定からIP一覧をみる
    • ターミナルでip a sコマンド実行して自分のIPを表示する
  2. ターミナルでssh ユーザ名@IPにてログインする
  3. VNCを有効にする(sudo raspi-config nonint get_vnc 0

f:id:ytyaru:20191204141709p:plain

 なお、値を1にすると以下エラー(sudo raspi-config nonint get_vnc 1)。

f:id:ytyaru:20191204145737p:plain

所感

 この成功は大きい。Pi4BをPCとして使う下地のひとつが整った。USB boot対応を待たずに。やったぜ!

前回まで

 ハード。

 ソフト。

 設定。

 企業。