ラズパイのyoctoイメージをUSBメモリから起動する（制限あり）

ほとんどのケースでSD(microSD)カードにOSとfile systemをインストールしてラズパイを立ち上げると思いますが、USBメモリからも同じように起動させることができたのでそのメモになります。

microSDカードも安く小さくて便利ですが、USBメモリも安くまた耐久・速度性の観点からもメリットあると思ってUSBメモリから起動する方法を調べました。

なのですが、Raspberry Pi OSによる起動方法が書かれたサイトや記事はたくさんある一方で、yoctoで作成したイメージを起動させる方法が見当たりませんでした。
そのあたりの詳細はページの後半で。

### やりたいこと
* Yoctoで作成したAGLのビルド済みイメージをUSBから起動させたい
* AGLイメージは [AGLのDLサイト](https://download.automotivelinux.org/AGL/release/octopus/15.0.1/raspberrypi4/deploy/images/raspberrypi4-64/ "Octopus 15.0.0")から取得 
(agl-demo-platform-crosssdk-raspberrypi4-64-20230406130135.rootfs.wic.xz) 

### やったこと
* /boot/cmdline.txtを編集してroot=/dev/sda2へ変更
* usbからImageを読めるようにboot.scrを再作成して、/bootへコピー

この２つで対応できました。前者はすぐ見つかったのですが２つ目に苦戦。。。

### 制限事項
* パーティションが作られたmicroSDカードを挿入している必要があります。（/dev/mmcblk0p1を探しに行く）

---
#### cmdline.txtを編集
作成したイメージをUSBメモリに書き込むとbootパーティションにcmdline.txtというのがあります。
デフォルトで「root=/dev/mmcblk0p2」となっているところを「root=/dev/sda2」に変更します。

```diff_shell
- dwc_otg.lpm_enable=0 console=serial0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait
+ dwc_otg.lpm_enable=0 console=serial0,115200 root=/dev/sda2 rootfstype=ext4 rootwait
```

#### boot.scrを再作成
raspberrypiではu-bootの処理をスクリプト化した「boot.scr」を実行するように作られていました。
デフォルトではmmcからImageファイルを読む作りになっているのでusbからloadできるように変更します。

ただし、boot.scrファイルはテキストファイルではないため直接編集することができないため、作り直しが必要です。

##### 1. 元ファイルを取得
 ```
 wget https://git.yoctoproject.org/meta-raspberrypi/plain/recipes-bsp/rpi-u-boot-scr/files/boot.cmd.in
 ```
##### 2\. boot.cmdを編集
```
cp boot.cmd.in boot.cmd
vi boot.cmd
```
```diff_shell
fdt addr ${fdt_addr} && fdt get value bootargs /chosen bootargs
-fatload mmc 0:1 ${kernel_addr_r} @@KERNEL_IMAGETYPE@@
-if test ! -e mmc 0:1 uboot.env; then saveenv; fi;
-@@KERNEL_BOOTCMD@@ ${kernel_addr_r} - ${fdt_addr}
+fatload usb 0:1 ${kernel_addr_r} Image
+if test ! -e usb 0:1 uboot.env; then saveenv; fi;
+booti ${kernel_addr_r} - ${fdt_addr}
```
##### 3. mkimageを使ってboot.scrへ変換
```
mkimage -A arm64 -T script -C none -n "Boot script" -d "boot.cmd" boot.scr
```
:::note 
mkimage コマンドはsudo apt install u-boot-toolsでインストールしてください(ubuntuの場合)
:::

#### USBメモリへコピー
作成したcmdline.txt, boot.scrをUSBメモリのBOOTパーティションへコピーしてファイルを上書きします。

#### 起動
では、さっそくUSBメモリをラズパイ4のUSBコネクタに接続して起動します。
ただなぜかmicroSDカードを挿さないとと起動しない（/dev/mmcblk0p1が見つからずにtimeout)問題に遭遇したため、microSDカードも挿した状態で起動してください。


## 詳細
to be continue...

<!-- 
usbメモリから起動する方法についてはこちらに書かれています。

https://gadgetrip.jp/2021/05/raspberry_pi4_usb_boot/

この記事はRaspberry Pi OSでUSBから起動する方法です。比較的新しいbootloaderが書き込まれていれば何も変更なく起動できるとのこと。
私の場合、起動できるUSBポート(USB3.0の上側）と起動しないポート(USB3.0の下側)がありました。（要調査？）

#### /dev/sdaに変える
Yoctoでの方法についてはこちらに記載がありました。root filesystemをUSBにする必要があるため、デフォルトのmmcblkからsdaに変更が必要です。ただし、こちらのブログはraspberry pi3であり2018年に書かれた内容のためYoctoの記載も若干古いです。

https://mickey-happygolucky.hatenablog.com/entry/2018/06/02/110042

試してみましたが、事前の予想通りrootのパーティションを変えるだけではNGです。kernel起動が始まりません。
Kernel imageやdevice treeの指定方法を調べる必要があります。

#### 同じ質問は見つかるが解がない？！
やはり同じことを考える人がいるようでmeta-raspberrypiのgithub issueに上がってました。
質問者は自己解決したようですがどうやって解決したのかは書いておらず不明のままです。
 
https://github.com/agherzan/meta-raspberrypi/issues/864

#### u-bootの環境を見てみる
経験上、`"usb start"` が必要だろうということで、試しにu-bootからコマンド実行してみました。
。。。
その際、printenvで既存の環境変数を見てみるとありました、usb startの記載。
-->

<!--

```
=> usb start
=> load usb 0:1 0x02400000 /boot.scr ; source 0x02400000
```

-->

### やり残し
* cmdline.txt, boot.scrで対応させること。
 => こちらは RFC(Request for Comment)としてPR投稿しました。
https://github.com/agherzan/meta-raspberrypi/pull/1175
* SDカード挿入の原因調査。raspberry piの標準環境でも起きるのか調査必要です。

### 履歴
| 版 |日付 | コメント |
|:-:|:-:|:-:|
| 0.1  |  2023/5/5 | 初版として  |