WindowsでRaspberry Piのイメージファイルを圧縮する

#背景
この記事では使用しているRaspberry Piのイメージファイルを圧縮する方法について説明をします。

Raspberry PiのイメージファイルをコピーするためにはWin32DiskImagerでマイクロSDのイメージファイルを作成し、それを別のマイクロSDに書き込めばよいのですが、簡単ではありません。
イメージファイルはマイクロSDの容量と同じファイルサイズになり、とてもサイズが大きくなります。加えて、マイクロSDはそれぞれ微妙にサイズが異なっているために同じ容量のマイクロSDだと書き込みできないときがあります。

# 効果
私がコピーや配布したRaspberry Piのイメージファイルは16GBのマイクロSDにRasbianのliteと、必要なアプリケーションを入れています。マイクロSDの使用領域は3.8GBですが、Win32DiskImagerでマイクロSDのイメージファイルを作成すると16GBになります。以下の作業によりファイルの圧縮を行って、最終的には1GB以下にすることができました。

今回はWindows PCでの作業を前提とします。MACはClassmethodさんの[Mac上でPiShrinkがインストールされたDockerコンテナを使用してRaspberry PiのSDカードのバックアップを作成する方法](https://dev.classmethod.jp/articles/shrink-raspberry-pi-os-image-size-using-pishrink-on-docker/)の記事がありました。

#準備するもの

Windows PC(windows 10)側アプリケーション
- VirtualBox 6.1 [こちら](https://www.virtualbox.org/wiki/Downloads)から本体とExtention Packをダウンロードし、本体とExtension Packの両方をインストールしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136933/fc6f169f-c239-ff89-82b1-db131874d9be.png)
- VirtualBOXで動かすubuntu [こちら](https://www.ubuntulinux.jp/products/JA-Localized/download)からダウンロードしてください。記事作成時は`ubuntu-ja-20.04.1-desktop-amd64.iso`が最新版でした。

# 流れ
1. Virtual BOXでubuntuを動かす
2. Virtual BOXとwindowsで共有フォルダの設定をして、ubuntuにマイクロSDのイメージファイルを渡す
3. マイクロSDの未使用領域を解放する。
4. PiShrinkでマイクロSDの無駄な領域を削除して、zip圧縮する

# 1. Virtual BOXでubuntuを動かす
1) virtual boxｗ立ち上げて「新規」をクリック
Ubuntuで作業しますので、適当な名称を付けてubuntuを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136933/12298fd8-98ed-e179-e744-f0ca6de61748.png)

メモリサイズはPCのメモリの半分程度にしました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136933/f8ea7056-5839-6619-1973-f7409311ea06.png)

続いて`仮想ハードディスクを作成する`→`VDI(VirtualBox Disk Image')`→`可変サイズ`→ハードディスクのサイズを設定→作成をクリックします。

2) 続いて起動をクリックしてubuntuのインストールをします。
起動をクリックすると画面が開きますので、ダウンロードしたubuntuのイメージファイルを設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136933/0f521321-a88f-4bd5-53f5-b54b4ca383b0.png)

しばらく時間がかかりますが、画面が出たら`ubuntuをインストール`をクリックします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136933/7a630534-c84b-2e5a-0166-3809a5dc76ea.png)

何回か画面に従ってクリックしていきます。そして最後にubuntuが再起動します。

# 2. Virtual BOXとwindowsで共有フォルダの設定をして、ubuntuにマイクロSDのイメージファイルを渡す

VirtualBOXのマネージャ画面で「共有フォルダー」の設定をクリックして任意のフォルダ（上段）とubuntu側でのマウント先を指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136933/26ea656f-6368-f62b-5fa1-e63b0043a7a8.png)

ubuntu側で実行してwindows側のshareフォルダを/mnt/shareにマウントします。
上段は最初の一回だけ実行してください。
下段は起動するたびに実行する必要があります。

```bash
sudo apt-get install virtualbox-guest-utils
sudo mount.vboxsf share /mnt/share
```

ここでWindowsに戻りWin32DiskImagerなどを利用してマイクロSDのイメージファイルをshareフォルダに保存してください。

# 3. マイクロSDの未使用領域を解放する。

続いて、ubuntuでファイル容量の削減をしていきます。

まず、imgファイルをubuntuにマウントします。
`sudo losetup -f`でマウント先を調べます。loop7がマウント先と返されました。

```bash
sudo losetup -f
> /dev/loop6
```

続いて、imgファイルをマウントします。
1行目でimgファイルをマウントし、2行目でパーティションの認識、3行目でgpartedを起動します。gpartedがインストールされていないときは`sudo apt-get install gparted`でインストールしてください。

```bash
sudo losetup /dev/loop6 /mnt/share/イメージファイル名.img
sudo partprobe /dev/loop6
sudo gparted /dev/loop6
```
gpartedを起動すると以下のようになりした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136933/aa2e631e-2361-655f-c5ab-82c181bb6cb8.png)

ext4 rootfsを右クリックしてリサイズを選択、パーティションを使用領域を限界まで小さくし、✔を押して保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136933/c0526ac4-533d-92aa-97c8-162fe9b16f59.png)

# 4. PiShrinkでマイクロSDの無駄な領域を削除して、zip圧縮する

[PiShrink](https://github.com/Drewsif/PiShrink)を利用してSDカードのイメージファイルから無駄な領域を削除します。
`sudo pishrink /mnt/share/イメージファイル.img`

自分が実行したときには15GBから3.1GBに圧縮できたと返ってきました。

出力されたimgファイルをzip圧縮して終了です。

```bash
zip -r zip後のファイル名 イメージファイル.img
```

#参照したサイト

http://linux900.blog.fc2.com/blog-entry-68.html

もっと良いやり方があったら教えてください。