[Raspberry Pi OS Lite] M.2 SSDへのOSの移行と「Unable to find root filesystem」エラー解消法

# はじめに
Raspberry Piのストレージとして一般的に使用されるSDカードは, 長期間使用すると故障しやすいという弱点があります. そのため, 耐久性やパフォーマンスの向上を目的として, SSDやUSBデバイスを用いた起動方法が広く採用されています.

デスクトップ版のRaspberry Pi OSでは, 標準で提供される「SD Card Copier」を使用してデータを簡単に移行できます. しかし, CLIであるLite版のOSでは, 別の方法が必要となります.

この記事では, [Argon ONE M.2 Case](https://argon40.com/products/argon-one-m-2-case-for-raspberry-pi-4)とM.2 SATA SSDを使用し, rpi-cloneを用いてデータを移行し, Raspberry Pi LiteをSSDから起動させる手順を解説します. 

また, 移行中に遭遇した
```
(initramfs) Unable to find root filesystem
```
というエラーの原因と, その解決方法について解説します.

## エラーの原因:
SSDの起動に必要なファイルの中に, SDカードの`PARTUUID`がそのまま残っていたことが原因でした. これを正しい`PARTUUID`に訂正することで解決できました.

## [Argon ONE M.2 Case](https://argon40.com/products/argon-one-m-2-case-for-raspberry-pi-4)とは?
>- フルサイズHDMIポートを2つ搭載
>- 電源管理モードを搭載
>- 赤外線リモコン（IR）サポート内蔵
>- M.2 SATA SSDに対応（Key-BおよびKey B&M対応）
>- Raspberry Pi 4の高速ブートと大容量ストレージを実現
>- UASP対応により、高速なデータ転送が可能
>- 伝統的なmicroSDカードに比べて、高速な起動時間と大容量ストレージを提供

翻訳引用: [Argon ONE M.2販売ページ](https://argon40.com/products/argon-one-m-2-case-for-raspberry-pi-4)
他にもGPIOピンが使えるなど, Raspberry Piの機能を拡張できるケースです.

# 1. rpi-cloneのインストール
まず, rpi-cloneをインストールします.
この時点では, SDカードから起動させています.
```
sudo apt install -y git
```
```
git clone https://github.com/billw2/rpi-clone.git
```
```
cd rpi-clone
```
```
sudo cp rpi-clone rpi-clone-setup /usr/local/sbin
```
# 2. SSDにデータ移行
まず, データを移行する前にデバイス名を確認します. 
この時点でも, SDカードから起動させています.

SSDを接続し, 以下コマンドを実行します.
```shell-session
lsblk
```
出力例:
```
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda           8:0    0 119.2G  0 disk 
|-sda1        8:1    0   512M  0 part 
`-sda2        8:2    0  28.5G  0 part 
mmcblk0     179:0    0    29G  0 disk 
|-mmcblk0p1 179:1    0   512M  0 part /boot/firmware
`-mmcblk0p2 179:2    0  28.5G  0 part /
```
今回はSDカードから起動しているため, mmcblk0がSDカードのデバイス名であることがわかります.
同様に, sdaはSSDのデバイス名であることがわかります.

\
それでは, rpi-cloneを使ってSSDにOSを移行していきます.
```
sudo rpi-clone sda
```
実行途中で以下のように聞かれるので, "yes"を入力します.
```
Do you want to initialize the destination disk /dev/sda? (yes/no): yes
```
データ移行が完了すると,
```
Hit Enter when ready to unmount the /dev/sda partitions...
```
と出るのでenterを押します. これで移行完了です.
# 3. 正しい`PARTUUID`への書き換え
手順2までの状態でSSDから起動すると,
```
(initramfs) Unable to find root filesystem
```
というエラーが出てしまいます.

その原因は, SSDの起動に必要なファイルの中に, SDカードの`PARTUUID`がそのまま残っていることでした.

そのため, 以下でファイルの中身を書き換えていきます.
※この時点でも, SDカードから起動しています.

まず, 以下のコマンドで, それぞれの正しい`PARTUUID`を確認します.
```
sudo blkid
```
出力例:

:::note warn
`PARTUUID`などの値は環境によって異なりますので, 適宜ご自身の環境に合わせてください.
:::
```shell
/dev/mmcblk0p1: LABEL_FATBOOT="bootfs" LABEL="bootfs" UUID="SDCARD-ABCD" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="SDCARD-01"
/dev/mmcblk0p2: LABEL="rootfs" UUID="sdcard-0a-1234" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="SDCARD-02"
/dev/sda2: LABEL="rootfs" UUID="ssd-0a-1234" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="SSD-02"
/dev/sda1: LABEL_FATBOOT="bootfs" LABEL="bootfs" UUID="SSD-1234" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="SSD-01"
```
## 3-1. `sda1`のファイル編集
次に, sda1をマウントします
```
sudo mount /dev/sda1 /mnt
```
```
cd /mnt/
```
以下で`cmdline.txt`の内容を参照すると,
```
cat cmdline.txt
```
以下のようになっています.
```shell
console=serial-sample console=tty1 root=PARTUUID=SDCARD-02 rootfstype=ext4 fsck.repair=yes rootwait cfg80211.ieee80211_regdom=JP
```
この`PARTUUID`は先ほど`$ blkid`で確認したSDカードの`PARTUUID`になってしまっています.
この値をSSDの`PARTUUID`である`SSD-02`に書き換えます.

:::note info
対応した`PARTUUID`は, `blkid`コマンドの出力結果を比較し, `LABEL`や`TYPE`を基に探すと見つけやすいです.
:::

```
sudo nano cmdline.txt 
```
`PARTUUID`の部分をSSDの`PARTUUID`に書き換えます.
```bash
console=serial-sample console=tty1 root=PARTUUID=SSD-02 rootfstype=ext4 fsck.repair=yes rootwait cfg80211.ieee80211_regdom=JP
```
変更前後を比較すると, 以下の通りになります.
```diff_shell
-console=serial-sample console=tty1 root=PARTUUID=SDCARD-02 rootfstype=ext4 fsck.repair=yes rootwait cfg80211.ieee80211_regdom=JP
+console=serial-sample console=tty1 root=PARTUUID=SSD-02 rootfstype=ext4 fsck.repair=yes rootwait cfg80211.ieee80211_regdom=JP
```
これでsda1について書き換えが完了しました.
アンマウントします.
```bash
cd && sudo umount /mnt/
```
:::note warn
ここで`cd`コマンドを実行しないと, `target is busy`というエラーが出てしまうので注意してください.
(僕はハマりましたTT)
:::


## 3-2. `sda2`のファイルの編集
先ほどと同じようにマウントします.
```
sudo mount /dev/sda2 /mnt
```
```
cd /mnt/
```
問題のファイルを確認します.
```
cat /etc/fstab 
```
以下のような中身になっていると思います.
```
proc            /proc           proc    defaults          0       0
PARTUUID=SDCARD-01  /boot/firmware  vfat    defaults          0       2
PARTUUID=SDCARD-02  /               ext4    defaults,noatime  0       1
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that
```
ここでも, 先ほどと同じ用にSDカードの`PARTUUID`が書かれています.

\
書き換える前に, もう一度`PARTUUID`を確認します.
```
blkid
```
出力結果
```bash
/dev/mmcblk0p1: LABEL_FATBOOT="bootfs" LABEL="bootfs" UUID="SDCARD-ABCD" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="SDCARD-01"
/dev/mmcblk0p2: LABEL="rootfs" UUID="sdcard-0a-1234" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="SDCARD-02"
/dev/sda2: LABEL="rootfs" UUID="ssd-0a-1234" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="SSD-02"
/dev/sda1: LABEL_FATBOOT="bootfs" LABEL="bootfs" UUID="SSD-1234" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="SSD-01"
```
nanoでファイルを編集します.
```
nano /etc/fstab
```
`vfat`と`ext4`にそれぞれ対応している`PARTUUID`を書き換えていきます. 
```
proc            /proc           proc    defaults          0       0
PARTUUID=SSD-01  /boot/firmware  vfat    defaults          0       2
PARTUUID=SSD-02  /               ext4    defaults,noatime  0       1
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that
```
変更前後を比較すると, 以下の通りになります.
```diff_shell

proc            /proc           proc    defaults          0       0
-PARTUUID=SDCARD-01  /boot/firmware  vfat    defaults          0       2
+PARTUUID=SSD-01  /boot/firmware  vfat    defaults          0       2
-PARTUUID=SDCARD-02  /               ext4    defaults,noatime  0       1
+PARTUUID=SSD-02  /               ext4    defaults,noatime  0       1
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that
```
書き換え完了です.

最後に, アンマウントします.
```bash
cd && sudo umount /mnt/
```
これで, SSDから起動することが可能になりました.

# おわりに
データを移行する方法は`dd`コマンドなど様々な方法がありますが, `rpi-clone`はシンプルでわかりやすかったです.
この経験で`PARTUUID`というものが存在していることやRaspberry Piの内部の仕組みについて知ることができ, 少し詳しくなることができました.

# 参考文献　
https://github.com/billw2/rpi-clone

https://qiita.com/ikemura23/items/4b7ab1af98045fa6516b

https://qiita.com/KEINOS/items/62b2abb9cc4f2d142cbb

https://uepon.hatenadiary.com/entry/2020/06/02/203949

https://qiita.com/tsukaman/items/240888d360cc58ac2a04

https://ossfan.net/setup/linux-36.html#rpi-clone%E3%81%AE%E5%AE%9F%E8%A1%8C

https://argon40.com/products/argon-one-m-2-case-for-raspberry-pi-4