Raspberry Pi 4を買った

最近、Raspberry Pi 3を自作HaskellライブラリーのAArch64での動作確認用に使っていた。だが何かとスペックが物足りないので、Raspberry Pi 4の最近新たに出たメモリ8GBモデルに環境を移行することにした。

色々あった結果、ラズパイ本体だけではなくストレージやOS(ディストリ)も変わった:

旧環境

  • Raspberry Pi 3 Model B (メモリ1GB)
  • /: microSD 16GB
  • OS: Ubuntu Server 18.04 LTS 64bit

新環境

  • Raspberry Pi 4 Model B (メモリ8GB)
  • /: USB接続SSD 250GB
  • OS: Ubuntu Server 20.04 LTS 64bit

購入物

秋葉原に行ったついでに以下の物品を購入した。

  • Raspberry Pi 4 Model B メモリ8GBモデル(本体)
  • ラズパイ用ACアダプター
  • ラズパイ4用ケース。ファンを使わなくても十分放熱してくれそうなやつ。(ラズパイ3の時点で発熱がすごかったので、ラズパイ4はさらに発熱することが予想された)

家に帰ってから気づいたのだが、ラズパイ4のHDMI端子はフルサイズではなくmicroHDMIだった。

ラズパイ4の端子類は、EthernetがGbE対応になってUSB 3.0に対応して電源がUSB Type-Cになったことは把握していたが、HDMI端子のサイズが変わったことは把握していなかった。HDMI端子が小型なのはラズパイZeroだと思って油断していたこともあるかもしれない(ラズパイ売り場にHDMIアダプターが並んでいてもZero用だと思って気に留めなかった)。

(HDMI出力が2本になっているのは、デジタルサイネージでの利用やマルチディスプレイ環境を想定しているのだろうか?)

とは言っても、普段はMacからSSH接続して使用しているので、ラズパイ自身のHDMI出力はそれほど重要ではない。なので、後述の方法でHDMI出力に頼らずに環境構築ができればmicroHDMIアダプターを買わなくてもどうにかできる…と思ったのだがうまくいかなかったので、トラブルシューティングのために結局microHDMI変換アダプターをポチった。

後日買ったもの:

  • microHDMIアダプター

「小型の」HDMI端子はデジカメに使われている印象がある。実際、自分が持っている一眼レフには小型のHDMI端子がついていたので、以前、それ用の変換アダプターを購入していた。それを利用できないかと家を探してみたが、出土したのはminiHDMIのアダプターだった(写真の真ん中)。「小型のHDMI」端子にはminiとmicroがあるのである。クソッタレ

  • USB接続SSD

当初は128GBくらいのmicroSDカードを買おうと思って思ったが、冷静に考えるとUSB接続SSDの方が容量単価が低いし読み書きが高速なのでSSDを買った(詳しくは後述)。パッケージに記載された読み書き速度が430MB/sの安いやつ。USB 3.0でしか接続できないラズパイごときに高速なNVMe SSDは必要ない。

ちっちゃい。Type-Cケーブルが付属していたが、SSD側の端子はUSB 3.0 microB

ラズパイ3のmicroSDカードをラズパイ4にそのまま挿して動くのか

ラズパイ3に乗っているCPUのアーキテクチャはArmv8.0-A, ラズパイ4に乗っているCPUのアーキテクチャもArmv8.0-Aである。ということは、ソフトウェア的な面ではラズパイ3とラズパイ4は互換性がある。なので、ラズパイ3のmicroSDカードをそのままラズパイ4に挿しても動作する可能性がある。

だが、現実はそう甘くなかった。

microSDのブート用パーティション(?)に入っているファームウェア(?)がこのモデル(ラズパイ4)に対応していないというようなエラーが出る。ラズパイ3側で起動してapt full-upgradeを実行しても同じく、である。

「ラズパイ3とラズパイ4にはソフトウェア(OS含む)的に互換性がある」というのは事実のはずで、公式のダウンロードリンクはラズパイ3とラズパイ4のリンク先が同一である。

よく見るとUbuntu Serverのダウンロードリンクには19.10と20.04は載っているが、18.04は載っていない。ラズパイ4ではUbuntu Server 18.04は動かない(?)が、Ubuntu Server 19.10や20.04なら動くかもしれない、という結論に至った。

果たして、 sudo do-release-upgrade -d によってUbuntu Serverのディストリを20.04へアップグレードしたら同じSDカードでもラズパイ4で動作した。

この節の結論としては、「基本的にはラズパイ3のSDカードをラズパイ4にそのまま挿しても動作するが、ディストリのバージョンが古いと動かない可能性がある」となるだろうか。

ラズパイ3(左)とラズパイ4(右)。4のケースは放熱を重視したものを選んだ

Haskell環境

筆者のラズパイの用途は主に「自作Haskellライブラリーの動作確認」であった。アーキテクチャに依存するライブラリーを書く場合、この時代にx86系でしか動作しない(あるいは、x86向けにしか最適化されていない)というのでは不味かろう、という動機である。

これまではUbunut Server 18.04上でStack 2.1.3を使ってGHC 8.8.3を動かしていた。しかし、Ubuntu Server 20.04上で同じことをすると

Unable to find installation URLs for OS key: linux-aarch64-tinfo6

というメッセージが表示されてGHCが動かない。また、Stack自身も、2.3.1ではAArch64向けのバイナリが配布されていないようだ。

(ちなみに、「Ubuntu Server 18.04でビルドしたバイナリをUbuntu Server 20.04で動かす」ことには問題ないようで、ビルド済みのベンチマークプログラムを走らせることはできた。その結果を見ると、ラズパイ4はラズパイ3の倍くらい速くなっているようだ。強い。)

こうなると、最悪自前でGHCをビルドする必要が出てくる。しかし、使っているストレージは16GBのmicroSDカードである。以前「複数のGHCを導入(8.6.5と8.8.3)」しようとしたところストレージの不足で失敗したので、本格的にHaskell環境を整えるにはもっと大容量のストレージを用意する必要がある。

外付けSSDの利用

16GBのmicroSDカードで不足なのであればもっと大容量のmicroSDカードを買えば良い。128GBとか。

そう思って電器屋に行って「どうせ挿す先がラズパイだからそこまで読み書きが高速じゃなくても良いな(読み書きが高速なカードはクソ高い)」「この5000円強くらいのやつが良さそう」などと考えていたが、気づいてしまった。

同じお金があれば、microSDの倍くらいの容量の外付けSSDが買えるのである。

軽くググった感じではラズパイのmicroSDカードの読み書き速度は50MB/sも出れば良い方で、そんなに高速な部類ではない。一方、USB 3.0でSSDを接続すればUSB 3.0の速度に見合った速度(500MB/sくらいのオーダー)で読み書きできることが期待できる。

用途がソフトウェアのビルドなので、ファイルシステムの読み書き速度は速ければ速いほど良い。そういうわけでUSB接続のSSDを買うことにした。ラズパイ4のインターフェースはUSB 3.0(最大5Gbps)なので、高速・高発熱な読み書きを謳うNVMe SSDの性能は必要ない。安いSATA SSDで十分である。

そういうわけで、店のレジ前で安売りされていたUSB接続SSDを買った。

SSDへの移行

ラズパイを外付けUSBデバイスから起動!と言ったときに、

  • microSDカードを完全に廃して、USB接続ストレージから起動する
  • ブート用のパーティションはmicroSDに残したまま、OSの入ったパーティション(Linuxの /)をUSB接続ストレージに移す

の2通りが考えられる。ラズパイ4は前者はできなくはないようだが、ラズパイのEEPROMの書き換えやら何やらが必要らしい。筆者は面倒くさがりなので後者を実践することにした。

まずは、SDカードの内容をSSDへコピーする。この手の作業には筆者は昔からGPartedを使っていたが、筆者の家にはGUIのLinuxが起動するマシンがなかったのでその辺のCD-RにGParted Liveを焼いてデスクトップ機で起動した。その上で、SSDをGPTでアレした上でLinuxの入ったext4のパーティションをコピーした。

データのコピー後、コピー先のラベル&UUIDはコピー元のラベルと別のものにしておく。ラベルは「writable」だったのを「writable-ssd」に変更し、UUIDはGPartedの「New UUID」で新しいものを設定した。

あとは、ブート時にSDカードではなくSSDからOSを起動するように設定を変えれば良い。そのためにはmicroSDにあるブート用のパーティション(FAT32でフォーマットされている)の中にある btcmd.txt および nobtcmd.txt を編集すれば良さそうだ。具体的には、 LABEL=writable となっている部分を、SSDに設定したラベルを使う LABEL=writable-ssd に変更する。

編集前:

$ cat /boot/firmware/btcmd.txt
net.ifnames=0 dwc_otg.lpm_enable=0 console=tty1 root=LABEL=writable rootfstype=ext4 elevator=deadline rootwait fixrtc
$ cat /boot/firmware/nobtcmd.txt
net.ifnames=0 dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=LABEL=writable rootfstype=ext4 elevator=deadline rootwait fixrtc

編集後:

$ cat /boot/firmware/btcmd.txt
net.ifnames=0 dwc_otg.lpm_enable=0 console=tty1 root=LABEL=writable-ssd rootfstype=ext4 elevator=deadline rootwait fixrtc
$ cat /boot/firmware/nobtcmd.txt
net.ifnames=0 dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=LABEL=writable-ssd rootfstype=ext4 elevator=deadline rootwait fixrtc

これでmicroSDとSSDをラズパイ4に接続すると、Linuxが立ち上がった。このLinuxがSSDから立ち上がっていることを確認するために mountdf -h を実行すると、 //dev/sda2 になっており、空き容量が210GBに増えていた。めでたしめでたし。

/dev/sda2 on / type ext4 (rw,relatime)
/dev/sda2 on / type ext4 (rw,relatime)
/dev/mmcblk0p1 on /boot/firmware type vfat: /boot/firmwareはmicroSDカードのまま
/ の総容量が229GB、空き領域が210GBに増えた

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です