純規の暇人趣味ブログ

首を突っ込んで足を洗う

Raspberry Pi 3をUSB(HDD)だけ(SD不要)で動かす

      2018/04/07    HimaJyun

Raspberry PiをUSB(HDD)で起動させる」というやり方は既にあります。

しかし、これは単にデータ(OS)の部分をHDDに移しただけであり、依然としてブートローダとなるSDカードは必要でした。

今回はそのブートローダとなるSDカードすら使わずに、USBストレージ1つで起動させられるようになったみたいなので試してみました。

スポンサーリンク

といっても公式のドキュメントや、その他ググって出る所に書いてある事とさほど変わりは無いのですが……そこでは書かれていないちょっとしたコツも。

木苺、USBで動く。

どうやら、Raspberry Pi 3でないと出来ないみたいです。

それから、環境を構築するまでの間はOS入りのSDカードが必要です。(頑張ればなくても出来そうだけど……)

OSはRasbianです、それ以外のディストリで出来るかは不明、NOOBSでインストールした場合は一筋縄では行かないかも……(というかNOOBSってそういう使い方するものじゃないよね?ないのか?)

木苺の下ごしらえ

USBからブートする方法は新しいファームウェアでサポートされた方法なので、まずはPi側でファームウェアの更新と設定変更を行います。

早い話が以下のコマンドをコピペで実行していけばOK

# Raspbian liteの場合はrpi-updateのインストールが必要
sudo apt-get update
sudo apt-get install -y rpi-update

# ファームウェアを更新する
# 前まではnextブランチから取得する必要がありましたが、安定版に取り込まれたらしい
sudo rpi-update

# USBブートを有効にする
echo "program_usb_boot_mode=1" | sudo tee -a /boot/config.txt

# タイムアウトを5秒にする(HDDの場合は多分必要)
echo "program_usb_boot_timeout=1" | sudo tee -a /boot/config.txt

# 再起動(再起動した段階で変更がハードに書きこまれるっぽい?)
sudo reboot

再起動した後に「vcgencmd otp_dump | grep 17:」を実行して「17:3020000a」となっていれば設定OK(ちなみに設定前は「17:1020000a」)

ちなみに、これらの設定はOTPと言って、一度書き込むと元に戻せません。つまり一度USBブートを有効にすると無効には戻せない(有効にしたままでも今まで通り使えるので問題はないです)

公式のドキュメントでは書かれていなかったが、USB HDDを使う場合「program_usb_boot_timeout」を設定しないときっと動きません。

これはタイムアウトをデフォルト(2秒)から5秒に引き延ばすためのオプションです。

HDDはスピンアップが必要なので、デフォルトの2秒ではきっとタイムアウトしてしまって起動しません。(場合によってはこの5秒でも足りなかったりするのですが……10秒にする方法とかないのだろうか?)

パーティションを作成する

ブートパーティションがFATでないとダメなのは変わらずです。

まずはUSBをPiに接続し、パーティションを作成します。

もちろんUSB上のデータは有無を言わさず全て消えるので、可愛い可愛い彼女(そんなものは居ない)の誕生日映像みたいなのをうっかり消してしまわないように注意しましょう。

USBをPiに刺すと、他に余計な物を繋いでいない限り「/dev/sda」として認識されるはずです。

「sudo parted /dev/sda」でパーティションの作成に移ります。

partedが入力待ちになったら、以下の通りに実行

GNU Parted 3.2
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) mktable msdos
Warning: The existing disk label on /dev/sda will be destroyed and all data on
this disk will be lost. Do you want to continue?
Yes/No? Yes
(parted) mkpart primary fat32 0% 100M
(parted) mkpart primary ext4 100M 100%
(parted) print
Model: Logitec Corp. LHR (scsi)
Disk /dev/sda: 320GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:

Number  Start   End     Size    Type     File system  Flags
 1      1049kB  99.6MB  98.6MB  primary  fat32        lba
 2      99.6MB  320GB   320GB   primary  ext4

(parted) quit

コピペ用、以下の内容をコピペすればOK

mktable msdos
Yes
mkpart primary fat32 0% 100M
mkpart primary ext4 100M 100%
print
quit

でもって、パーティションをフォーマットする。

sudo mkfs.vfat -n BOOT -F 32 /dev/sda1
sudo mkfs.ext4 /dev/sda2

データのコピー

データはrsyncで移す模様、rsyncが入っていない場合は入れる。

sudo apt-get install -y rsync

マウントしてからrsyncでコピーする

sudo mkdir -p /mnt/target
sudo mount /dev/sda2 /mnt/target/
sudo mkdir /mnt/target/boot
sudo mount /dev/sda1 /mnt/target/boot/
sudo rsync -ax --progress / /boot /mnt/target

cmdline.txtとfstabの修正

そのままではHDD上の/boot/cmdline.txtや/etc/fstabがSDカード(mmcblk0p)を指したままなのでHDDに変更する

Stretchからcmdline.txtやfstabの指定がPARTUUIDを使うようになったので、「ls -l /dev/disk/by-partuuid/」でPARTUUIDを確かめておく。

後はエディタで「/mnt/target/boot/cmdline.txt」「/mnt/target/etc/fstab」を開いて該当の部分を書き換える

proc /proc proc defaults 0 0
PARTUUID=24e66acb-01 /boot vfat defaults 0 2
PARTUUID=24e66acb-02 / ext4 defaults,noatime 0 1
# a swapfile is not a swap partition, no line here
# use dphys-swapfile swap[on|off] for that

(従来までの/dev/sda1などで指定しても問題ない)

SSHホスト鍵の更新

USBで動かす事とは関係ない気がするが……公式のドキュメントではSSHのホスト鍵を更新していたので同じように更新しておく

cd /mnt/target
sudo mount --bind /dev dev
sudo mount --bind /sys sys
sudo mount --bind /proc proc
sudo chroot /mnt/target
rm /etc/ssh/ssh_host*
dpkg-reconfigure openssh-server
exit
sudo umount dev
sudo umount sys
sudo umount proc

USBでブートするか確認

アンマウントして電源を切る

cd ~
sudo umount /mnt/target/boot 
sudo umount /mnt/target
sudo poweroff 

その後、電源ケーブルを抜いてからSDカードを抜き、もう一度電源を投入する(もちろんUSBは繋いだまま)

上手く行っていればPiが起動する。

USB HDDを使う時の難点

コツというか……

「program_usb_boot_timeout」でタイムアウトを5秒に引き延ばしたが、手元にあるHDD(USB接続のケースに入っている)はどれも5秒でもスピンアップしなかった

ので、一度スピンアップさせたら(HDDが動き始めたのにOSが起動しない状態を確認したら)電源を抜いてすぐに入れなおす、手持ちのケースはこれでなんとか起動する。(rebootは問題なし)

まだまだアレ、もしタイムアウトを10秒とか、更に引き延ばす方法があるなら知りたい。(でも多分なさそう)

rootdelay、bootcode_delay、boot_delay(boot_delay_ms)、どれもブートローダーをロードした後の物らしく、それ以前の話である今回の問題には効果なさそう……SDカードを使う従来までの手法の方が安定する。

感想

SDカード要らないヒャッホーーーー!!!、と思ったがそうでもない、タイムアウトする……

というかPiにSATA端子が付いてくれれば(SATA端子を付けるボード、的なのは販売されている)

Pi4はメモリ2GでSATA端子搭載になるとイイナァ~

 - コンピューター