CM4 (Raspberrypi) の ブートデバイス切り替え(eMMC->NVME)に苦労した話

世界的にRaspberry PIが入手しづらくなっている現在，Compute Module 4略してCM4も選択肢の一つ．<br/>元々は組み込み用のようですがサポートデバイス（例えば<a href="https://www.waveshare.com/product/raspberry-pi/boards-kits/compute-module-4-cat/cm4-to-pi4-adapter.htm">こんなの</a>とか）を使えば行けるかなと思い購入しました．<br/>が，オンボードの記憶デバイスではあっという間に足りなくなり，<br/>拡張ボード経由で接続したNVME SSDからのブートにしようとしたら苦労したのでシェアします

# 使ったデバイス
<ul><li>CM4 (eMMC8G,Memory8G)<li>拡張ボード(Waveshare Mini Base Board(A)): 公式ページは<a href="https://www.waveshare.com/product/raspberry-pi/boards-kits/compute-module-4-cat/cm4-io-base-a.htm">こちら</a><br/>（筆者マレーシア在住で，<a href="https://my.cytron.io/c-raspberry-pi/c-raspberry-pi-main-board/c-raspberry-pi-cm/p-raspberry-pi-cm4-wireless-8gb-ram-8gb-emmc-and-kits">こちら</a>のセットを購入しました）<li> SSD(128GB)

## 苦労するポイント
世の中には散々RaspberryPIをUSBやSSD起動する方法が拡散されていますが本件の場合
* オンボードストレージが8GBモデルのためLITE Ver.しかインストールできずGUIが使えない(eMMC32GB版は買えませんでして．．）
* CM4はオンボードでのブートローダ書き換えができない
以上の点がかなりの参考記事を適応不可能にしています

# やること
基本的にやることは次の通りです
* オンボードeMMCへのOSインストール（本記事では割愛[^1]）
* ブートローダの書き換え（起動デバイス順序変更）
* SSDへのファイルの転送

## ブートローダの書き換え
筆者Windows環境をメインとしていますので，git bash上での作業を説明します（元記事にはMACでの例もあったはず）<br/>
### rpibootのコピー
インストールされたrpibootを別の場所にコピー[^2]
~~~Powershell
> copy 'C:\Program Files (x86)\Raspberry Pi\' [どこか中のファイルを編集できるところ]\rpiboot
~~~
### boot.confの編集
recoveryディレクトリの中のboot.confを編集します
~~~ini:boot.conf
BOOT_ORDER=0xf25641
~~~
となっているのを６（NVME）が１（オンボードeMMC)より右側に来るようにします(右から起動順になるようです）
~~~ini:boot.conf
BOOT_ORDER=0xf25146
~~~
### pieeprom.binのダウンロード及び生成
以下の操作はgit bashで行います
~~~shell
~$ cd [rpibootのコピー先]/rpiboot/recovery #リカバリーディレクトリに入る
recovery$ rm -f pieeprom.original.bin #ブートローダイメージオリジナルを削除
recovery$ curl -L -o pieeprom.original.bin https://github.com/raspberrypi/rpi-eeprom/raw/master/firmware/stable/pieeprom-2022-12-07.bin #ブートローダオリジナルイメージをダウンロード
~~~
最後のバイナリデータは<a href=https://github.com/raspberrypi/rpi-eeprom/tree/master/firmware/stable>こちら</a>を参照して日付の新しいファイル[^3]を選ぶ，もしくは直接クリックしてダウンロードすればいいです<br/>ダウンロードしたら先ほど編集したboot.confをもとにブートローダを生成します
~~~shell
recovery$ ./update-pieeprom.sh
~~~
おそらく次のような出力を目にするはずです
~~~shell
/home/pi/usbboot/tools/rpi-eeprom-config --config boot.conf --out pieeprom.bin pieeprom.original.bin set +x 
new-image: pieeprom.bin 
source-image: pieeprom.original.bin 
config: boot.conf
~~~

### CM4ボードへの転送
以下のコマンドを実行し，書き込みモードにしたCM4[^4]をUSBでPCに接続します
~~~shell
recovery$ ../rpiboot.exe -d .
~~~
(最後の.をお忘れなく)
OSをインストールした時のように下記のような出力が得られると思います
~~~
RPIBOOT: build-date Dec 16 2022 version 20221215~105525 5a25e04b
Loading: recovery/bootcode4.bin
Waiting for BCM2835/6/7/2711…
Loading: recovery/bootcode4.bin
Sending bootcode.bin
Successful read 4 bytes
Waiting for BCM2835/6/7/2711…
Loading: recovery/bootcode4.bin
Second stage boot server
Loading: recovery/config.txt
File read: config.txt
Loading: recovery/pieeprom.bin
Loading: recovery/pieeprom.bin
Loading: recovery/pieeprom.sig
File read: pieeprom.sig
Loading: recovery/pieeprom.bin
File read: pieeprom.bin
Second stage boot server done
~~~

## SSDへのファイル転送（CUI環境）
以下の作業はRaspberryPI上で行いますのでRaspberryPIを起動し，コンソールを繋ぐなりSSHで入るなりしてください
(起動順を変更済みでもSSD上に何もなければオンボードeMMCないしSDカードから起動します）

### rpi-cloneのダウンロード及び修正
CUI環境ではrpi-cloneというプログラムで転送できますのでgithubから落とします
~~~
git clone https://github.com/billw2/rpi-clonet.git
~~~
そのままではNVMEデバイスのマウントに失敗するので1060行目あたりを修正します
~~~shell:rpi-clone(old)
if [[ $dst_disk == *"mmcblk"* ]]
~~~
↓
~~~shell:rpi-clone(new)
if [[ $dst_disk == *"mmcblk"* || $dst_disk == *"nvme"* ]]
~~~
デバイス名を確認して
~~~shell
$ lsblk
NAME         MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
mmcblk0      179:0    0   7.3G  0 disk
|-mmcblk0p1  179:1    0   256M  0 part /boot
`-mmcblk0p2  179:2    0     7G  0 part /
mmcblk0boot0 179:32   0     4M  1 disk
mmcblk0boot1 179:64   0     4M  1 disk
nvme0n1      259:0    0 119.2G  0 disk
|-nvme0n1p1  259:1    0   256M  0 part
`-nvme0n1p2  259:2    0   119G  0 part
~~~
nvme0n1というのが今回の対象になります
~~~shell
$ rpi-clone nvme0n1
{省略}
~~~
再起動して，例えばdf -hやlsblkコマンドなどでMOUNT POINTが移動していることを確認
~~~shell
$ lsblk
NAME         MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
mmcblk0      179:0    0   7.3G  0 disk
|-mmcblk0p1  179:1    0   256M  0 part 
`-mmcblk0p2  179:2    0     7G  0 part 
mmcblk0boot0 179:32   0     4M  1 disk
mmcblk0boot1 179:64   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 /
~~~

# まとめ
CM4のBoot loaderがNVMEに対応したのが比較的最近なためか，なかなかまだ情報があまりなく，<br/>大半の記事でboot.confによる起動順の変更は言及されていましたが，<br/>pieeprom.origin.binの更新がないと起動順が変更できませんでした．

# 参考
基本的には下記ページを参考にしました<br/><a href="https://notenoughtech.com/raspberry-pi/it-took-me-2-months-to-boot-cm4-from-nvme/">It took me 2 months to boot CM4 from NVMe</a><br/>2か月苦労した筆者の記事を3日足らずで見つけられてよかった．．<br/>

[^1]: 例えば<a href=https://houwa-js.co.jp/2021/10/raspicm4/>こちら</a>参照
[^2]: CM4をセットアップする際に既にインストールしたかと思いますが，デフォルトでProgram Files以下に入ったり管理者権限がないと編集できなかったり面倒なので改めて別の場所に移しました
[^3]: この記事を執筆した時点では2023-01-11が最新でした
[^4]: CM4インストールできてるならやり方は分かりますよね（サポートデバイス依存なので書き(け)ません)