RaspberrypiやTinkerboardといったシングルボードコンピュータ(SBC)ではOSを記録する媒体としてmicroSDカードやeMMCを使用しています。Win32DiskImagerといったツールでmicroSDカードやeMMCのバックアップを取った後に別のmicroSDカードやeMMCにリストアするとサイズ違いでエラーが発生し、リストアできない場合が時々あります。
microSDカードやeMMCは同じ容量でもロットやメーカによってセクタサイズが若干、異なります。小さい容量のバックアップデータから同じ容量もしくは大きい容量にリストアする場合は問題ありませんが、容量が小さい場合、エラーが発生して起動できません。パーティションに空きがあったとしてもパーティションサイズは不正なため、起動に失敗します。このような場合にはバックアップデータファイルのパーティションを操作とイメージファイルの編集が必要です。今回はバックアップしたイメージファイルをLinux(ubuntu)上で編集してOSイメージをリサイズする方法を紹介します。
■大まかな流れ
1. 縮小したいイメージファイル(*.img)をマウント
2. gpartedでドライブを縮小
3. 縮小して未使用の領域を除く
■手順
1. *.imgファイルをマウントするために空きのループデバイスを確認する。下記のコマンドで空いているループデバイス一覧が表示されます。
sudo losetup -f
2. イメージファイル(*.img)を空きのループデバイスにマウントする。下記の例では空きのloop8にXXX.imgをマウントした場合を示す。
sudo losetup /dev/loop8 XXX.img
3. ループデバイスを更新する。
sudo partprobe /dev/loop8
4. パーティションを編集するためにパーティションツールを起動させる。
sudo gparted /dev/loop8
※gparted がインストールされていない場合は事前にsudo apt-get install gparted を実行しておく。
5. GUI上でドライブのext4パーティション(パーティション2)を右クリックし、[リサイズ/移動]をクリックする。右端をスライドさせてパーティションを縮小する。今回はセクタサイズの若干の差のため、数MiBでも大丈夫だと思いますが念のために100MiB~500MiB程度、縮小しました。
6. gparted の適用ボタンを押して変更を反映させる。
※この時点ではシステム上のパーティションサイズが小さくなっただけでイメージファイル(*.img)の容量は変わっていません。イメージファイルの未使用パーティションの空き領域をイメージファイルから削除する必要があります。
7. イメージファイルのパーティションセクタサイズを確認する。
sudo fdisk -l /dev/loop8
↑エル
下記のように表示されます。Endのセクタ位置が重要です。パーティションの最終セクタの位置をメモします。
デバイス ブート Start End Block Id System
UUUUUUU BBBB CCCC AAAA * Fat
WWWWW * YYYY ZZZZ AAAA * Linux
8. ループデバイスを解除する。(追記)
sudo losetup -d /dev/loop8
9. イメージファイルの空き領域を削除します。
sudo truncate --size=$[(ZZZZ+1)*512] XXX.img
※重要な点は最終セクタから次の空き領域を削除するため、パーティションの最終セクタ+1を設定する点です。
これでイメージファイル(*.img)を縮小することができました。今回はVirtualBox上で実行したUbuntuでファイル操作を行いました。他にも専用スクリプトやresize2fsを使用する方法などありますが、環境によってうまくいかない場合がありました。上記の方法だと手間はかかりますが、RaspberrypiやTinkerboard、Nanopiといった様々なSBCでも適用できると思います。