はじめに
Raspberry Pi Compute Module (以下、CM)を採用した産業用ラズパイでは、これまでにお伝えした通りSSDドライブやmicroSDカードでも起動ができます。基本はeMMC起動が一般的です。
CM4は、Raspberry Pi 4(以下、Pi 4)や5と異なり、eMMCにあるブートローダーもそのままでは書込ができません。以前、PL-R4ではディップスイッチを書込可能に設定した後、別のデバイスからUSB経由で転送して入れ替えられることをお伝えしました。
eMMCに入っているOS(システム領域)も同じ仕組みです。イメージファイルをUSBケーブルで書き込みします。やや面倒に感じますが、安易に入れ替えできない仕組みになっています。
産業用ラズパイでは手順こそひと手間増えますが、ddコマンドでバックアップし、PiShrinkで圧縮すれば書き込み時間も短縮できて便利です。
一般的なPi 4やPi 5でもシステムを丸ごとイメージファイルとしてバックアップする際、今回と同じようにddコマンドを使います。参考にしてください。
今回の環境
イメージファイルを転送する先がCM4ということもあり、作業用デバイスにPi 4を利用しました。作業用デバイスはWindows機でも可能です。
- 作業用デバイス:Raspberry Pi 4 (bookworm) 64bit (Pi 4)
- バックアップするデバイスはPL-R4(CM4)
- RPI BOOTを使用(Windows機はrpiboot_setup.exe)
- USB-A to Cケーブルを使用
- ddコマンド(またはwic拡張子のbmap方式も対応)
- Pi Shrinkで圧縮
Raspberry Pi OSは、アップデートとアップグレードを済ませてあります。(記事執筆時点で最新)
イメージファイルをバックアップするのに、WindowsならWin32 Disk Manager、Linux環境ならddコマンドを使うのが一般的です。
- Win32 Disk Manager(Windows)
- ddコマンド(Linux)
更に今回はCM4のバックアップなので、ddコマンド実行の前にRPI BOOTの実行が必要になります。
RPI BOOTのインストール
RPI BOOTを作業用のPi4にインストールします。ホームディレクトに作成しました。
(Windows機ならrpiboot_setup.exeでインストール:https://github.com/raspberrypi/usbboot/tree/master/win32)
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 recovary
Pi 4(またはWindows機)のRPI BOOTを実行してから、作業用デバイスとPL-R4(CM4)をUSBケーブルで繋ぎ、ddコマンドでバックアップをしていきます。
RPI BOOTの実行
RPI BOOTを実行後、PL-R4のディップスイッチを書込可能側に切り替えてから作業用Pi4とUSBケーブルで接続します。
Windows用RPI BOOTも同じ手順です。
RPI BOOTの実行は次の通りです。
cd ~/usbboot/recovary
sudo ../rpiboot -d .
このケースだとrecovaryディレクトリにイメージファイルがバックアップされます。
USBケーブルを接続後にエラーがなければ、作業用デバイスにしたPi 4のデスクトップにストレージとして認識したダイアログが出ます。
これでddコマンドが実行できるようになりました。
バックアップを取りたいPL-R4と作業用デバイスはRPI BOOTの実行後にUSBケーブルで接続します。1つ注意が必要です。
CM4のRPI BOOTはUSB2.0で動作します。
そのため作業用デバイスのPi 4側のUSB2.0ポートに接続してください。
接続する先がCM4に限り、USB3.0ポートだとI/Oエラーでスタックしました。
公式ドキュメントにも書いてあります。
- CM5 EEPROM は、デフォルトで MMC、USB-MSD、USB 2.0 (CM4 のみ)、ネットワーク、NVMe ブートをサポートし
ています。代替ブート モード (ネットワークなど) から Linux を起動して、nRPIBOOT GPIO を低くできること、およ
び USB 2.0 インターフェイスが動作していることを確認してください。
https://github.com/raspberrypi/usbboot?tab=readme-ov-file#troubleshooting
ddコマンドの実行
ddコマンドを実行するのにバックアップ元である領域を指定する必要があります。
fdiskコマンドで確認ができます。sudo fdisk -l
今回、USBケーブルで接続されたCM4は/dev/sdb
となっているのが分かります。
sudo fdisk -l /dev/sdb
Disk /dev/sdb: 29.12 GiB, 31268536320 bytes, 61071360 sectors
Disk model: 0001
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: 0x4ef66861
Device Boot Start End Sectors Size Id Type
/dev/sdb1 8192 1056767 1048576 512M c W95 FAT32 (LBA)
/dev/sdb2 1056768 61071359 60014592 28.6G 83 Linux
/dev/sdbと分かったところで、ddコマンドを使ってバックアップしていきます。
ブロックサイズの指定
ddコマンドはファイルの指定とブロックサイズ(bs)の指定をします。
オプションがたくさんあります。少なくてもbsを指定しconv=syncを指定すればcountは省略しても構いません。
bsで指定するバイト数は、読み書き1回辺りのブロックサイズです。512バイトがデフォルト値です。
使用されるメディアの物理ブロックサイズの倍数にします。(512なら1024(1M)…4096(4M)など)
単純にブロックサイズが大きい方が速くはなるのですが、エラーがあった場合はそのサイズごと壊れてしまうため小さい数値の方が無難です。仮にブロックサイズを大きくしても、結果として完了が遅くなる場合もあります。
進捗状況が分かるstatus=progress
をオプションとして付けます。これがないといつ終わるのか把握できません。
ddコマンドの書式例(イメージファイル化)
sudo dd if=/dev/sdb of=backup-bookworm-4m.img bs=4M status=progress
ifはInFileの略で、ofはOutFileの略です。ですから、if=読み込み先、ofが書き出し先です。
Raspberry Piの公式ドキュメントでは、書き込む際にbs=4Mとあったため、バックアップも4Mにしてみました。
公式ドキュメント:https://www.raspberrypi.com/documentation/computers/compute-module.html#flash-the-emmc
結果、31GBで、転送速度は9.9 MB/sとあり、完了までおよそ52分でした。
31268536320 bytes (31 GB, 29 GiB) copied, 3159.45 s, 9.9 MB/s
今回はUSB2.0ということもあり、bs=4Mで良いと思います。
個人的にRaspberry Piでは、古くは容量16GBでUSB2.0だったことから、bs=1Mを多用していました。
バックアップしたイメージファイルを復元するのは、やはりddコマンドで書き込みします。
このままだとファイルサイズも大きく復元にも時間がかかるため、出来上がった.imgファイルを圧縮していきます。
PiShrinkで圧縮
出来上がったイメージファイルを書き込む手順も29GB程度ではやはり1時間近くかかってしまいます。
実は各パーティション(bootfs、rootfs)で実際に使っている領域はそこまで多くはありません。
今回の例だと、sdb1とsdb2の実際の使用量は、75MB/512MBと4.7GB/29Gです。
ファイルシス サイズ 使用 残り 使用% マウント位置
/dev/sdb1 510M 75M 436M 15% /media/raspida/bootfs
/dev/sdb2 29G 4.7G 23G 18% /media/raspida/rootfs
バックアップから復元する際、できるだけ速く書込を行うために、出来上がったイメージファイルを圧縮してから書き込むことにします。
使っている領域だけで圧縮すれば、ファイルサイズは小さくなり、イメージファイルを保存するにも容量を圧迫しません。書き込む総時間も短くなり一石二鳥です。
イメージファイルを圧縮するアプリケーションは「PiShrink」です。
PiShrink:https://github.com/Drewsif/PiShrink
圧縮されたイメージファイルで書き込んだ後、パーティションの情報をみると、空き容量が多くなっているのが分かります。
従来のRaspberry Pi OSは、この空き領域はraspi-configから手動で拡張していました。
しかし、現行バージョンは起動時において自動的に領域を拡張(Expanded)してくれます。
PiShrinkは、バックアップされたイメージファイルから使用済みサイズまでパーティションを縮小させています。空き容量を含まないため、ファイルサイズが小さくなるというわけです。
PiShrinkのインストールと実行
先ずはじめに、必要なパッケージをインストールしておきます。
記事執筆時点のbookworm最新バージョンでは、pigzだけインストールされていませんでした。
sudo apt update && sudo apt install -y wget parted gzip pigz xz-utils udev e2fsprogs
wgetでスクリプトファイルをダウンロードし、実行権を与えて/usr/local/bin
にコピーします。
wget https://raw.githubusercontent.com/Drewsif/PiShrink/master/pishrink.sh
chmod +x pishrink.sh
sudo mv pishrink.sh /usr/local/bin
これで準備は完了です。
PiShrinkは次の書式で使います。
今回はバックアップしたイメージファイルは~/usbboot/recovary
に作成しましたので、移動して次のコマンドです。
cd ~/usbboot/recovary
sudo pishrink.sh backup-image-name.img
元の.imgファイルがそのまま圧縮されたサイズに置き換わります。
結果、30GBあったのが7.1GBへ小さくなりました。
pishrink.sh: Gathering data
Creating new /etc/rc.local
pishrink.sh: Checking filesystem
rootfs: 144755/1846656 files (0.1% non-contiguous), 1345322/7501824 blocks
resize2fs 1.47.0 (5-Feb-2023)
pishrink.sh: Shrinking filesystem
resize2fs 1.47.0 (5-Feb-2023)
Resizing the filesystem on /dev/loop0 to 1720340 (4k) blocks.
Begin pass 3 (max = 229)
Scanning inode table XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
The filesystem on /dev/loop0 is now 1720340 (4k) blocks long.
pishrink.sh: Zeroing any free space left
pishrink.sh: Zeroed 1.8G
pishrink.sh: Shrinking partition
pishrink.sh: Truncating image
pishrink.sh: Shrunk backup-image-name.img from 30G to 7.1G
オプション無しでも充分にリサイズされます。
バックアップしたイメージファイルを書き込む
テストとして復元先をUSBメモリーに指定して書き込んでみました。
同じPi4からなので、Raspberry Pi Imagerでも良いのですが、せっかくですからddコマンドで書き込んでみます。
USBメモリーの場所は、同じようにsudo fdisk -l
で調べると分かります。今回は/dev/sdc
でした。
ブロックサイズ(bs)は4Mで、書式はif=とof=のパスがバックアップした時とは逆になっています。
sudo dd bs=4M if=backup-image-name.img of=/dev/sdc conv=fsync status=progress
PiShrinkで7.1GBに小さくしたイメージファイルです。
使用領域によって変わりますが、今回の書き込み時間はおよそ10分程度で済みました。
使用したUSBメモリーは容量64GBです。
bmap方式での書込も対応
イメージファイルの中には、以前までの拡張子.imgではなく.wicを見かけます。これはbmap方式です。
bmap方式のイメージファイルでも、このRPI BOOTを使ったCM4への書き込みに対応しています。
bmap方式はddコマンドより速いと言われます。
これはブロックマッピングで最適化され、コピーされるデータが少なくなるためイメージ全体をコピーする方法より速くできるからです。
加えて、wicはイメージを生成後(bitbake)にwksファイルでイメージファイルを生成することも可能です。
本来、Yocto meta-raspberrypi環境で独自のイメージを作成することに利用されるのが一般的でしょうか。
既存のイメージファイルからbmaptool createコマンドで生成することもできます。
この場合は書込速度としての優位はあまりありません。少し速いですけどね。
bmap方式は、組み込みLinuxに携わっている人にも馴染みがある方法で効率的に書き込むことができます。
試しにbmap-toolsをインストールして、バックアップしたイメージファイルからbmapファイルを作成してみました。
sudo apt install bmap-tools
PiShrinkなどで圧縮する前のイメージファイル(RAWディスクイメージ)からbmap形式に出力します。
bmaptool create -o bmap-file-image.bmap backup-image-name.img
ここで生成された.bmapファイルを指定して、同じくbamptoolコマンドで書き込むことができます。
bmapについて詳しくはYocto Projectやbmap-toolsを参考にしてください。
- https://ja.wikipedia.org/wiki/Yocto_Project
- https://github.com/intel/bmap-tools
- https://manpages.ubuntu.com/manpages/focal/man1/bmaptool.1.html
イメージファイルのバックアップ
Pi 4やPi 5では、何もせずddコマンドがそのまま通ります。
今回のようなPL-R4を含むCM4へは、予め書込可能な状態に設定を変更し、RPI BOOTを実行すれば同じようにddコマンドを扱えます。
イメージファイルをPiShrinkで圧縮することで、書き込みの時間短縮が行えます。
ファイルサイズが小さければ、バックアップとしてイメージファイルを保存するにも利便性が高まりますね。
産業用ラズパイでもddコマンドでバックアップや復元する方法でした。
記事寄稿:ラズパイダ
非エンジニアでも楽しく扱えるRaspberry Pi 情報サイト raspida.com を運営。ラズベリーパイに長年触れた経験をもとに、ラズベリーパイを知る人にも、これから始めたいと興味を持つ人にも参考になる情報・トピックを数多く発信。PiLinkのサイトへは産業用ラズベリーパイについて技術ブログ記事を寄稿。