はじめに
Raspberry Pi 5(以下、Pi 5)では、PCIe接続ポートが本体に装備され、NVMe接続のSSDドライブが一般的なPCのように使えるようになりました。実はPCIeの使用は拡張HATが前提にはなりますが、Raspberry Pi 4(以下、Pi 4)から使用可能になっています。
Compute Module 4(以下、CM4)もPi 4と同様です。
ここでは、産業用ラズパイ「PL-R4」にNVMe接続のSSDドライブを実装して、起動ドライブとして扱う方法をご紹介します。
SSDドライブ起動のメリット
堅牢性を重視する産業用ラズパイでは、不意な電源シャットダウンでシステムが破損するのを避けるため、ファイルシステムをROM化をする必要も出てきます。ROMは読込専用(Read Only Memory)のことです。
一般的なRaspberry Piでは、microSDカードにOSを入れるのが基本ですから、データ領域と分けることが難しくなります。
産業用に使われるCM4は、eMMC起動が基本です。使用していないmicroSDカードも使えるため、eMMCにあるファイルシステムをROM化しても、microSDカードを別のデータ領域として使えるメリットがあります。
eMMCはmicroSDカードより速いといっても、SSDドライブには敵いません。より高速な処理が必要な場合は、eMMCの代わりにSSDドライブを起動ドライブにすれば、同じようにmicroSDカードを別の領域に使うことができます。
他にも、microSDカードは破損する確率も高いのがデメリットです。その点もeMMCやSSDドライブの方が優れています。更に速度が速いためSSDドライブで起動するメリットは大きいといえます。
使用した産業用ラズパイ「PL-R4」は、NVMe接続のSSDドライブが本体に実装できるように設計されています。
少々複雑なため次からの手順を参考にしてください。
SSD起動させるブートローダーの編集と書込み
CM4のブートローダーを書き換えるには、Pi 4のように単独ではできません。
CM4が搭載されている産業用ラズパイ「PL-R4」本体とは別に、市販されているPi 4を用意します。(別のPL-R4本体も使用できますが、今回はPi 4を使用します)
書き込みに使用する「rpiboot」ツールソフトをソースからビルドして使います。
書き込みに使うPi 4 はSSH接続ができたり、VNCで遠隔で操作できるよう事前にセットアップしておきました。
他にもCM4の書き込みにUSBケーブルが必要になります。USBケーブルで書き込み用ポートとPi 4を繋いでブートローダーを送り込む必要があるからです。
必要なもの:
- PL-R4本体
- Pi 4一式
- USB type-C to type-Aケーブル
- ソースからビルドした「rpiboot」
- microHDMIケーブル
- ディスプレイ
使用するケーブルは、CM4側がUSB-Cタイプのコネクタ形状で、Pi 4はUSB-Aタイプで少々特殊なため注意してください。
「USB-C to A」で検索すれば該当の商品が見つかるでしょう。
CM4は単独でEEPROMの更新ができない
一般的なPi 4であれば、rpi-eeprom-update
コマンドが使えます。
しかし、CM4では実行できません。
sudo rpi-eeprom-update
rpi-eeprom-update is not enabled by default on CM4.
The recommended method for flashing the EEPROM is rpiboot.
See: https://github.com/raspberrypi/usbboot/blob/master/Readme.md
Run with -h for more information.
少し面倒ですが、ある意味ではEEPROMの間違いは起こりにくくなりますね。
これ以降は別に用意したPi 4側で実行していきます。
ブートローダー(bootloader)の編集と入替え
NVMe接続のSSDドライブ起動に変更したい場合、市販のPi 5などではsudo rpi-eeprom-config
コマンドで設定ができます。CM4も基本は同じなのですが、書き換えたブートローダーごと入れ替えないとなりません。
CM4にファイルを送り込むのに「rpiboot」というツールソフトを使用します。物理的にUSBケーブルで接続したCM4に送り込む形です。
手順の流れはこうです。
別に用意したPi 4に、特定バージョンのブートローダーに対し、SSDドライブから起動するオプションを施して組み直します。
出来上がったブートローダーを、「rpiboot」ソフトを使いCM4へ書き込んで入れ替えることで、オプションを追記したことと同じになります。
ブートローダーのバージョン
始める前にPL-R4側でバージョンをチェックしました。2023−01−11でした。ファイル名だと「pieeprom-2023-01-11.bin」です。
vcgencmd bootloader_version
2023/01/11 17:40:52
version 8ba17717fbcedd4c3b6d4bce7e50c7af4155cba9 (release)
timestamp 1673458852
update-time 0
capabilities 0x0000007f
今回は記事執筆時点で最新の「pieeprom-2024-10-21.bin」を使用しました。
stableとlatestでは「pieeprom-2024-10-21.bin」が最新でした。以下、使用するファイルが異なる場合、年月日の部分は置き換えてお読みください。
各ファームウェアファイルの更新履歴を確認して、希望のバージョンを選んでください。
rpi-eeprom:https://github.com/raspberrypi/rpi-eeprom/blob/master/releases.md
rpibootの利用
rpibootは公式から推奨されているようにソースからビルドして用意します。
以下のようにgit cloneします。ホームディレクトリで作業しました。
sudo apt install git libusb-1.0-0-dev pkg-config build-essential
git clone --recurse-submodules --shallow-submodules --depth=1 https://github.com/raspberrypi/usbboot
cd usbboot
make
cd recovery
これより/usbboot/recovary
内にて作業します。
ファームウェアの場所
git cloneを実行した後、Pi 4(bookworm)では以下のディレクトリにファームウェアのファイルが展開されていました。
/lib/firmware/raspberrypi/bootloader-2711/stable
/lib/firmware/raspberrypi/bootloader-2711/latest
/lib/firmware/raspberrypi/bootloader-2711/default
どうやらbookwromになってからbootloader-2711
とbootloader-2712
にディレクトリ構造が分かれました。2712はPi 5用です。CM4は2711の中から選ぶことになります。
※bullseyeでの場所は、/lib/firmware/raspberrypi/bootloader/
でした。
ブートローダーからconfファイルを抜き出して追記
始めにブートローダーから設定ファイルを抜き出します。
rpi-eeprom-config /lib/firmware/raspberrypi/bootloader-2711/latest/pieeprom-2024-10-21.bin -o boot.conf
すると、recovaryディレクトリ内に元々ある空のboot.confが書き換わります。これを編集します。
sudo nano boot.conf
起動順(ブート順)を設定するBOOT_ORDER=0xf16
を追記します。
[all]
BOOT_UART=0
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=0
BOOT_ORDER=0xf16
Pi 5ではBOOT_ORDER=0xf461
などど設定していました。起動の順番を数字の部分を右から優先されます。
代表的なのは、1がmicroSDカード、4がUSB接続のストレージ、6がNMVe接続のSSDドライブです。
今回のBOOT_ORDER=0xf16
は、NVMe → microSDカードの起動順を表しています。
詳しくは公式ドキュメントでご覧ください。
URL:https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#boot_order-fields
256ハッシュ値の書き出し
sha256sumコマンドでpieeprom.binのハッシュ値を.sigファイルとして書き出します。
sha256sum pieeprom.bin | awk '{print $1}' > pieeprom.sig
整合性を照合するためです。
pieeprom.binへ書き出す
最後に書き出します。
先程追記したboot.confを含めたpieeprom-2024-10-21.binをpieeprom.binとして書き出します。
rpi-eeprom-config -c boot.conf -o pieeprom.bin /lib/firmware/raspberrypi/bootloader-2711/default/pieeprom-2024-10-21.bin
これで準備は完了です。
rpibootを実行してEEPROMへ書き込む
最後にrpibootを実行し、EEPROMへブートローダーを書き込みます。
USBケーブルとピンセット、ディスプレイとHDMIケーブルを用意しておきましょう。
コマンドの実行の前に、PL-R4をディスプレイとHDMIケーブルで繋いでおきます。(PL-R4本体の電源は入れない)
cd usbboot/recovary
sudo ../rpiboot -d .
実行後、次のようにWaitingになりターミナルの表示が止まります。
この時に書き換えたいPL-R4にUSBケーブルを繋きます。
**PL-R4に電源は要りません。単純にUSBケーブルでPi4と繋ぐだけです。
sudo ../rpiboot -d .
RPIBOOT: build-date Oct 27 2024 version 20240422~085300 c944557b
Loading: ./bootcode4.bin
Waiting for BCM2835/6/7/2711/2712...
このときEEPROMの書込み可にするため、ピンセットなどを使うディップスイッチをWRT側(向かって右)に切り替えます。
USBケーブルが接続されると、外部メディアとして認識されて書き込みが始まります。(/media/ユーザー名/にマウントされる)
次のような正しい結果例の通りならOKです。書き込めました。
sudo ../rpiboot -d .
RPIBOOT: build-date Oct 27 2024 version 20240422~085300 c944557b
Loading: ./bootcode4.bin
Waiting for BCM2835/6/7/2711/2712...
Loading: ./bootcode4.bin
Sending bootcode.bin
Successful read 4 bytes
Waiting for BCM2835/6/7/2711/2712...
Loading: ./bootcode4.bin
Second stage boot server
Loading: ./config.txt
File read: config.txt
Loading: ./pieeprom.bin
Loading: ./pieeprom.bin
Loading: ./pieeprom.sig
File read: pieeprom.sig
Loading: ./pieeprom.bin
File read: pieeprom.bin
Second stage boot server done
正常に書き込みが完了すると、PL-R4に繋いだディスプレイが緑色に点灯します。
これで書込は無事に終わりました。
失敗する時に確認したい事項
上手く行かずにハマったのは、次の2点でした。
1つは、数年前と異なり、ビルドするのにgit cloneしますが、submoduleも含めないとエラーが出ました。
最新情報は、のページで確認しましょう。
usbboot:https://github.com/raspberrypi/usbboot
もう1つはbookworm以降、/lib/firmware/raspberrypi/bootloader〜にある.binファイルまでのパスが変更されていました。
今は、Pi5用のbootloader-2712ディレクトリとそれ以外のbootloader-2711ディレクトリに分かれているのですね。
最後に確認したいのはUSBケーブルです。
品質の悪いケーブルだったり、TypeCへの変換コネクタを使っていると上手く行かない場合もあります。
滅多にはないことですが、どうしてもエラーになるなら別のケーブルで確認しましょう。
PL-R4側で書き換えの確認
以上の手順でEEPROMへ書き換えが成功しました。
接続していたUSBケーブルを取り外します。
【注意】起動させる前にPL-R4のディップスイッチを元に戻すのを忘れずに行います。(今度は左へ)
正常にできたのか確認のため、PL-R4の電源を入れて立ち上げて確認してみましょう。
ブートローダーのバージョンを確認してみます。
今回使用したファームウェア「pieeprom-2024-10-21.bin」が使用されていますか?
vcgencmd bootloader_version
BOOT_ORDERも指定した通りに書き込まれていました。
sudo rpi-eeprom-config
[all]
BOOT_UART=0
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=0
BOOT_ORDER=0xf16
NVMeの接続と速度の比較
起動の順番を書き換えたので、NVMeに接続するSSDドライブを用意し、OSイメージファイルを書き込みます。
「PL-R4」はPiLinkのダウンロードページで、モデル別、バージョン別にダウンロードができます。
書き込んだOSは、PL-R4用に用意されているOSイメージ(bullseye)をダウンロードしてRaspberry Pi Imagerのカスタムにて書き込みました。
SSDドライブに書き込むには、M.2 SSD専用のディスクステーションがあると良いでしょう。
今回は代用として、市販のSSDドライブ外付けケースに入れて別のPCから書き込みました。
USBケーブルで接続することで、microSDカードと同様に外付けメディアと認識できます。いつものようにRaspberry Pi Imagerで書き込むだけです。
SSDドライブ起動の確認
SSDドライブ起動にするためブートローダーを変更し、SSDドライブにOSも書き込んだので、Pl-R4本体へ接続して確認してみましょう。
本体底面にSSDドライブも接続できるコネクタがあります。しっかりとネジ止めして準備完了です。
電源を入れる前に、eMMCの書き込みディップスイッチを戻し忘れずOFF(左側)にしてください。書き込み可能なまま(WRT側)だと起動しません。
では早速、いくつかのコマンドで確かめてみます。
dfコマンドで/dev/nvme0n1p1が/bootにマウントされているのが分かります。
df -h
ファイルシス サイズ 使用 残り 使用% マウント位置
/dev/root 118G 4.2G 109G 4% /
devtmpfs 1.8G 0 1.8G 0% /dev
tmpfs 1.8G 0 1.8G 0% /dev/shm
tmpfs 724M 1.2M 723M 1% /run
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
/dev/nvme0n1p1 255M 32M 224M 13% /boot
tmpfs 362M 28K 362M 1% /run/user/1000
fdiskコマンドでみるともう少し詳細が分かります。
sudo fdisk -l /dev/nvme0n1
Disk /dev/nvme0n1: 119.24 GiB, 128035676160 bytes, 250069680 sectors
Disk model: TS128GMTE452T2
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: *******
Device Boot Start End Sectors Size Id Type
/dev/nvme0n1p1 8192 532479 524288 256M c W95 FAT32 (LBA)
/dev/nvme0n1p2 532480 250069679 249537200 119G 83 Linux
lsblkコマンドでは、microSDカード、eMMC、NVMe接続のSSDドライブがあり、NVMeに/bootがマウントされているのが分かります。
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
mmcblk2 179:0 0 29.1G 0 disk
└─mmcblk2p1 179:1 0 29.1G 0 part /media/pi/9016-4EF8
mmcblk0 179:32 0 29.1G 0 disk
├─mmcblk0p1 179:33 0 512M 0 part
└─mmcblk0p2 179:34 0 28.6G 0 part
mmcblk0boot0 179:64 0 4M 1 disk
mmcblk0boot1 179:96 0 4M 1 disk
nvme0n1 259:0 0 119.2G 0 disk
├─nvme0n1p1 259:1 0 256M 0 part /boot
└─nvme0n1p2 259:2 0 119G 0 part /
速度を調べる
続いてSSDドライブの速度を調べてみます。
hdparmコマンドで読み込み速度を計測してみました。
計測にはPL-R4本体でコマンドを実行し計測しています。
NVMe
NVMe接続のSSDドライブは375MB/sと出ています。
sudo hdparm -t /dev/nvme0n1
/dev/nvme0n1:
Timing buffered disk reads: 1130 MB in 3.00 seconds = 376.54 MB/sec
Pi 5が販売されている今となっては忘れてしまいがちになりますが、今回はCM4にSSDドライブ起動です。Pi 5のようにPCIeに完全対応していませんから、速度としてはやや物足りないとはいえ桁違いですね。
eMMC
次はeMMCです。
sudo hdparm -t /dev/mmcblk0
/dev/mmcblk0:
Timing buffered disk reads: 250 MB in 3.02 seconds = 82.88 MB/sec
eMMCは約82MB/sでした。
microSDカード
最後にmicroSDカードです。
sudo hdparm -t /dev/mmcblk2
/dev/mmcblk2:
Timing buffered disk reads: 28 MB in 3.09 seconds = 9.06 MB/sec
市販されているPi 4のmicroSDカード起動とは違い、今回の「PL-R4」ではおよそ10MB/s前後と速度が出ていません。これは製品独自のものです。
一般的なRaspberry Pi では概ね20〜30MB/sでしょうか。
今回の速度テスト結果
比較するまでもなく、SSDドライブの速度は充分な速さでした。
Result | SSD | eMMC | microSD Transcend32GB |
---|---|---|---|
読込速度 | 約376MB/s | 約82MB/s | 約10MB/s |
※microSDカードは「PL-R4」仕様と調整による値
複数回の実行
hdparmは簡易的な計測です。次のコマンドで複数回実行させてみると良いでしょう。
for i in $(seq 5); do sudo hdparm -t /dev/mmcblk2; sleep 5; done
スコアで比較
もう1つ、ネットで計測を共有できるスクリプトツールでも計測してみました。
こちらもやっていることはhdparmコマンドと同じです。より細かい表示と、独自のスコア採点方法で速度を比べられます。
こちらも結果は同じような読込355MB/sでした。
同スクリプトツールは、これまでユーザー名raspidaとして登録してきました。Pi4、Pi5や条件が異なるSSDドライブが登録されています。
どうぞ参考にしてください。
PiBenchmarks:https://pibenchmarks.com/user/raspida/
CM4でもSSDドライブ起動
一般的なPi 4と違い、CM4でのブートローダー変更は少々面倒に感じるかもしれません。
それでも、PL-R4は書込切替用のディップスイッチがあるため、CM4を拡張ロジックボードで使うより分かりやすくなっています。
記事執筆時点でも、手順通りに進めれば何も問題無く完了することができました。
それに、起動順序はEEPROMに書き込まれるので一度変更してしまえば済みます。
SSDドライブは、microSDカードやeMMC起動よりも速度の恩恵が大きいため、Raspberry Piを使用する内容によっては必須になってくるでしょう。
microSDカードを別のデータ領域にすることで、万が一のときも含め使い勝手が良くなると想像できます。
CM4でもSSDドライブ起動にしてみましょう。
記事寄稿:ラズパイダ
非エンジニアでも楽しく扱えるRaspberry Pi 情報サイト raspida.com を運営。ラズベリーパイに長年触れた経験をもとに、ラズベリーパイを知る人にも、これから始めたいと興味を持つ人にも参考になる情報・トピックを数多く発信。PiLinkのサイトへは産業用ラズベリーパイについて技術ブログ記事を寄稿。