ラズパイ4で64bit OSをmSATA接続のSSDから起動させる

最初に書いておくと、盛大にハマりました。
この手の記事はぐぐればたくさん引っかかるし皆さんうまくいっているようです。
ただ失敗の記事はあまり引っかからないので書いとこうかなと思ったわけですね。

買ったもの

購入したのは、Raspberry Pi 4 Model B (メモリ8GB)です。
ヨドバシで共立プロダクツのスターターセットを購入しました。
付属のSDカードにはRaspberry Pi OS 32bit版が入っていました。

$ sudo dmesg | grep Machine
[    0.000000] OF: fdt: Machine model: Raspberry Pi 4 Model B Rev 1.4

$ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

$ uname -a
Linux raspberrypi 5.10.17-v7l+ #1403 SMP Mon Feb 22 11:33:35 GMT 2021 armv7l GNU/Linux

速いストレージにしたかったので外付けのSSDも一緒に買おうと思ったのですが、ちょっと急いでいたのでヨドバシの購入ページでお勧めされていたトランセンドのmSATA3/128GB(TS128GMSA370)を一緒に買いました。
今思うとこれが良くなかった。いまさらマイナーなmSATAを買う事もなかったんだよね。ちゃんと調べとけばなー。
届いてからUSB3.0へ変換するケースが必要な事に気がつき、AmazonでZheinoのUSB3.0-mSATAケースを買いました。(アホだな)

https://www.amazon.co.jp/gp/product/B06XSD129T/

ついでに自分のモニターにはHDMIがないのでHDMI DVI変換アダプター HDMIメスタイプ BSHDADVも買いました。

www.buffalo.jp

ちゃんと調べないから、始めるまでが長いw

ブートローダー(EEPROM)の設定

結論から言うと、最新化する必要はありませんでした…

初期状態で以下のようになっています。
2020-09-03版ですね。

$ sudo rpi-eeprom-update
BOOTLOADER: up-to-date
   CURRENT: 202093日 木曜日 12:11:43 UTC (1599135103)
    LATEST: 202093日 木曜日 12:11:43 UTC (1599135103)
   RELEASE: default (/lib/firmware/raspberrypi/bootloader/default)
            Use raspi-config to change the release.

  VL805_FW: Using bootloader EEPROM
     VL805: up-to-date
   CURRENT: 000138a1
    LATEST: 000138a1

$ vcgencmd bootloader_version
Sep  3 2020 13:11:43
version c305221a6d7e532693cc7ff57fddfc8649def167 (release)
timestamp 1599135103
update-time 0
capabilities 0x00000000

最新のほうがいいかなと思って、 FIRMWARE_RELEASE_STATUS="stable" にしてから2021-03-18版にしましたが、必要はなく元に戻しています。

USBで起動出来るようにしておく必要はあります。
初期状態の設定は以下のようになっています。

$ vcgencmd bootloader_config
[all]
BOOT_UART=0
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=0
DHCP_TIMEOUT=45000
DHCP_REQ_TIMEOUT=4000
TFTP_FILE_TIMEOUT=30000
TFTP_IP=
TFTP_PREFIX=0
BOOT_ORDER=0x1
SD_BOOT_MAX_RETRIES=3
NET_BOOT_MAX_RETRIES=5
[none]
FREEZE_VERSION=0

起動の優先順位をUSBにするには raspi-config で簡単に出来ます。

$ sudo raspi-config
→ 6 Advanced Options   Configure advanced settings
  → A6 Boot Order      Choose network or USB device boot
    → B2 USB Boot      Boot from USB if available, otherwise boot from SD Card

これでSDカードを抜かなくてもUSBから起動します。(USBが無ければSDカードで上がります)
この設定をすると再起動が要求されますが、一度シャットダウンしておきます。
SSDから64bit OSで起動している現在の設定は以下のようになっています。
(BOOT_ORDER=0xf14 となっている所がUSB起動の設定です)

$ vcgencmd bootloader_config
[all]
BOOT_UART=0
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=0
DHCP_TIMEOUT=45000
DHCP_REQ_TIMEOUT=4000
TFTP_FILE_TIMEOUT=30000
ENABLE_SELF_UPDATE=1
DISABLE_HDMI=0
BOOT_ORDER=0xf14

SSDへOS書き込み

今どきは、Raspberry Pi Imagerで簡単に書き込みが出来ます。
Mac版のRaspberry Pi Imagerを以下からダウンロードして起動します。

www.raspberrypi.org

32bit版ならこのツールから自動でダウンロードして書き込みまでしてくれますが、せっかくの8GBを有効利用したいので64bit版のRaspberry Pi OSを自分でダウンロードします。
今回は 2021-03-04-raspios-buster-arm64.zip を使います。
ここから落としました。

ftp.jaist.ac.jp

ホスト名やSSHWiFiの設定をあらかじめ出来ます。
Ctrl+Shift+x で設定画面が出てきますので設定しました。

CHOOSE OS から Use custom を選択し、あらかじめダウンロードしておいた 2021-03-04-raspios-buster-arm64.zip をセットします。

CHOOSE SD CARD で、Macに繋げたSSDを選択します。

WRITE を押します。

簡単です。

SSD起動

64bit OSを書き込んだSSDをラズパイにつなぎます。
当然、USB 3.0の口につなぐのですがこれでハマりました。

まず初回起動時ですが、root filesystemにある空き容量を検知して勝手にパーティションのリサイズが始まります。
これが結構時間がかかるので、LEDランプの点滅が収まるまで辛抱強く待ちましょう。うちは30分以上掛かりました。

その後、起動プロセスが始まるのですがなぜか EXT4-fs error が大量に出続けます。
fsck掛けたり、あらかじめパーティションを拡張しておいたり、EEPROMのバージョンを戻したり(最初は2021-03-18でやってた)、ケーブルを変えてみたり別のSSDと別のケースを持ってきたり、色々試しましたがどうしても解消しません…
いろいろぐぐって、このページにあるようにUSB 2.0にSSDを差し替えるとあっけなく起動しました。

qiita.com

何だったんだ…

諦めきれず、他に情報がないか調べていたら今度はこちらのサイトにあたりました。

signal-flag-z.blogspot.com

これがビンゴ!!
自分もこの記事と同じ、 JMicron Technology Corp. / JMicron USA Technology Corp. JMS567 SATA 6Gb/s bridge でした。

この記事の通りやって無事、USB 3.0で起動しました!

まずはとりあえずUSB 2.0につないだ状態で起動して設定します。

$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 152d:0578 JMicron Technology Corp. / JMicron USA Technology Corp. JMS567 SATA 6Gb/s bridge
Bus 001 Device 003: ID 1bcf:0029 Sunplus Innovation Technology Inc.
Bus 001 Device 002: ID 2109:3431 VIA Labs, Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

$ lsusb -t
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 3: Dev 3, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
        |__ Port 4: Dev 4, If 0, Class=Mass Storage, Driver=uas, 480M

JMicronのチップが使われているようです。
Driverが uas になっている事が確認出来ます。
こちらの記事によるとUSAは、USB Attached SCSIというプロトコルで、USB mass-storageより高速なのですが、ドライバの実装がよくないと遅くなる事があるようです。

www.raspberrypi.org

/boot/cmdline.txtカーネルパラメーターを追加して、usb-storageで動作するようにします。
先頭に usb-storage.quirks=152d:0578:u というパラメータを入れます。改行は入れてはダメです。

$ sudo vi /boot/cmdline.txt
console=serial0,115200 console=tty1 root=PARTUUID=7ff05857-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles
↓
usb-storage.quirks=152d:0578:u console=serial0,115200 console=tty1 root=PARTUUID=7ff05857-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles

これでシャットダウンして、SSDをUSB 3.0の口に差し替えます。
電源を入れると起動しました!すばらしい!!

$ lsusb
Bus 002 Device 002: ID 152d:0578 JMicron Technology Corp. / JMicron USA Technology Corp. JMS567 SATA 6Gb/s bridge
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 2109:3431 VIA Labs, Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

$ lsusb -t
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
    |__ Port 2: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 5000M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M

ちゃんとドライバが切り替わっているようです。(※マウスは外しちゃいました)
一応簡単にベンチマーク取っておきます。

  • SDカード
$ sudo hdparm -t /dev/mmcblk0p2

/dev/mmcblk0p2:
 HDIO_DRIVE_CMD(identify) failed: Invalid argument
 Timing buffered disk reads:  28 MB in  3.00 seconds =   9.32 MB/sec
  • USB 2.0でのSSD
$ sudo hdparm -t /dev/sda2

/dev/sda2:
 Timing buffered disk reads: 112 MB in  3.03 seconds =  36.97 MB/sec
  • USB 3.0でのSSD
$ sudo hdparm -t /dev/sda2

/dev/sda2:
 Timing buffered disk reads: 690 MB in  3.00 seconds = 229.96 MB/sec

やったね。ちゃんと速くなってるよ!
フルスペックじゃないにしてもまあいいでしょう。
しかし、使い始めるまで長かったなー。

結論

ちゃんと下調べして買おう…