Ubuntu Weekly Recipe

第827回Raspberry PiサイズのRISC-VボードであるMilk-V MarsでUbuntuを動かす

第814回の1500円以下で買えるRaspberry Pi PicoサイズのRISC-VボードなMilk-V DuoでUbuntuを動かすでは、Milk-V Duoなる小型のRISC-Vボードに無理やりUbuntuをインストールしてみました。実はMilk-VはさまざまなサイズのRISC-Vボードをリリースしており、そのひとつがカードサイズのMilk-V Marsです。

今回はこのMilk-V MarsにUbuntuをインストールしてみましょう。大丈夫です。前回ほどひどいことにはなりません。

図1 RISC-VなシングルボードコンピューターであるMilk-V Mars

Ubuntuでも公式にサポートするMilk-V Mars

Ubuntu Weekly Topicsでも既報の通り、Ubuntu 24.04 LTSではMilk-V Marsを公式にサポートしています。さらには「Milk-VとCanonicalはハードウェアスポンサーシップの元、Milk-Vが新規に投入するプロダクトに向けてUbuntuが利用できるようにする」こともアナウンスされているのです。つまり今後もMilk-Vの製品のうちUbuntuが動く程度に十分に高性能なデバイスは、Ubuntuのイメージの提供が期待されます[1]

さて、Milk-Vの様々なRISC-V製品の中でもMilk-V Marsはいわゆる「Raspberry Piっぽい」シングルボードコンピューターです。

図2 Milk-V Mars(真ん中)とRaspberry Pi 5(右⁠⁠、VisionFive 2(左)との比較

コネクターの配置はRasperry Pi 5よりも3Bに似ていますが、あくまで「似ている」というだけで、電源コネクターがUSB-Cなどそれなりの差異は存在します。タイトなケースでなければ、Raspberry Pi 3B向けのケースやファン・ヒートシンクを使ってみるのも良いかもしれません。

そんなMilk-Vのスペックは次のとおりです。

  • SoC:Starfive JH7110 64bit SoC with RV64GC(4コア、1.5GHz)
  • LPDDR4 2GB / 4GB / 8GB
  • eMMC用ソケットコネクター
  • microSDカードスロット
  • SPI Flash(ブートローダー用)
  • HDMI出力
  • MIPI CSI/DSI
  • 1000BASE-T x 1
  • USB3 x 3、USB2 x 1
  • M.2 E-key端子
  • USB-C給電ポート(5V/3A)
  • 40ピンのGPIOヘッダー
  • PoEコネクター
  • FANコネクター(2ピン、5V)
  • オーディオジャック

電源はUSB-Cの5V/3A以上を使います。Raspberry Piの4や5で使っているものを流用すれば問題ありません。SoCはStafFiveのJH7110(SiFiveのU74コア)を搭載しています。つまり第806回でも紹介したVisionFive 2と同じです。

なお先日話題になったRISC-V CPU向けの攻撃手法であるGhostWriteは、T-Head製のCPU向けの話ですので、このSoCには影響ありません。ちなみにMilk-V DuoはT-HeadのC906を搭載していますが、脆弱性そのものはC910向けの話ではあるため、関係なさそうです[2]

また、Milk-V MarsはRaspberry PiのCompute ModuleのようなMilk-V Mars CMも用意されています。ただしCompute Moduleとしては、SO-DIMMタイプの製品のリリースも予定されているようです。公式サイトにはJetson NANOのベースボードに接続可能なMilk-V Jupiter NXや、Jetson Xavier NX互換のMilk-V Megrez NXなどが掲載されています。またこれらのモジュールをクラスター化できるMilk-V Cluster 08なんてものも用意されているので、RISC-Vでいろいろ遊びたい人はこのあたりを待ってみるのも良いかもしれません。

Milk-V MarsにUbuntuをインストールする

それではMilk-V MarsにUbuntuをインストールしてみましょう。最低限必要なのは次の機材です。

  • microSDカード
  • USBストレージ(インストール方法次第)
  • LANケーブル
  • 5V/3A以上に対応したUSB-Cの給電装置
  • シリアルコンソールケーブル

microSDカードやUSBストレージはUbuntuのインストール先です。プレインストールイメージをそのまま使うのであればひとつあれば十分ですし、UbuntuサーバーのLiveインストーラーを使いたいのであればインストラー用のメディアとインストール先のストレージの両方を用意する必要があります。

ただしMarsのSPI Flashを最新版に置き換えるのであれば、一度はmicroSDカードからの起動が必要になります。よって初回起動のときだけmicroSDカードが別途必要です。これについては後ほどインストール手順のところでも紹介します。

ちなみに本体(SoCだけでなくRJ-45のコネクター部分など)はかなり熱くなります。そのためUSBストレージを使う場合は、熱の影響で相性問題があるようです。たとえば小型のUSB-SSDとして有名なバッファローのSSD-PSTU3-BAシリーズなどは、Ubuntuのインストール自体は問題なく行えるものの、起動してしばらくすると固まったり起動しなくなったりしました。それに対してI-O DATAのSSPS-USシリーズは筐体サイズが大きいおかげか特に問題なく動いています。うまく動かない場合は別のUSBストレージに切り替えてみましょう[3]

また、2024年8月時点でUbuntuにおいてMarsのHDMIコネクター(やGPU)はうまく動きません。よってMarsにアクセスするためにはシリアルコンソールかSSH接続のどちらかになってしまいます。ここでは第806回と同じようにRaspberry Pi Debug Probeを使うことにします。

Debug Probeの接続

GPIO上のUARTピンは次のようなレイアウトになっています

  • GND(pin 6⁠⁠:Debug ProbeのGND(黒線)を接続
  • TX(pin 8⁠⁠:Debug ProbeのRX(黄線)を接続
  • RX(pin 10⁠⁠:Debug ProbeのTX(橙線)を接続
図3 実際はVisionFive 2のときと同じ接続になる

あとはPC側で任意の端末プログラムを使って接続するだけです。Debug Probeの場合は/dev/ttyACM0として見えますので、おそらく次のように接続することになるでしょう。

$ picocom -b 115200 /dev/ttyACM0

picocomについては、第684回のUbuntuからRaspberry Pi Picoを使うでも軽く紹介しています。

ブートデバイスの選択

Milk-V Marsはボード上のDIPスイッチで起動デバイスを選択できます

図4 USBポートの手前にあるDIPスイッチ。右手前の4ピンはPoEコネクター

ボードの外側が0、内側が1で、それぞれ次のような意味を持っています。

  • GPIO1=0、GPIO0=0:SPI Flashから起動
  • GPIO1=0、GPIO0=1:microSDカードから起動
  • GPIO1=1、GPIO0=0:eMMCから起動
  • GPIO1=1、GPIO0=1:UARTから起動

Ubuntuのイメージを使う場合、次のように選択する必要があります。

  • プレインストールイメージを使うのであれば、microSDカードからの起動とする
  • Liveインストーラーからインストールするのであれば、SPI Flashからの起動とする

SPI Flashにはベンダー(Milk-V)が作成したブートローダーがインストールされています。ベンダーのイメージを起動するのであればこれで問題ないのですが、Ubuntuのイメージの場合はUbuntu用のパッチがあたったブートローダーを使うことが推奨されているのです。

プレインストールイメージはmicroSDカード用のイメージにベンダーのブートローダーが入っているため、そこから起動するのが良いでしょう。しかしながらLiveインストーラーを起動するためには、SPI FlashにUbuntuに対応したブートローダーをインストールしておかなくてはなりません。そこでインストールのステップとしては次のような手順になります。

  1. DIPスイッチをあらかじめmicroSDカードから起動する設定にする
  2. プレインストールイメージを使って起動する(microSDカードで運用するならここで完了)
  3. プレインストールイメージからSPI Flashのブートローダーを更新する
  4. DIPスイッチをSPI Flashから起動する設定に変更する
  5. Liveインストーラーを起動してUbuntuをインストールする

1から4までは一度だけ行えば十分です。あとはUbuntuを再インストールすることになっても5だけを実施すれば良いことになります。今回は1から5までのすべての手順を紹介することにします。

このあたりについてはUbuntuのWikiページも参考になります。

プレインストールイメージからのUbuntuの起動

まずはプレインストールイメージをダウンロードしmicroSDカードに書き込みます。

$ wget https://cdimage.ubuntu.com/releases/24.04/release/ubuntu-24.04-preinstalled-server-riscv64+milkvmars.img.xz
$ xzcat ubuntu-24.04-preinstalled-server-riscv64+milkvmars.img.xz | sudo dd bs=1M conv=fsync status=progress of=デバイス

ここで「デバイス」「/dev/sda」などmicroSDカードが接続されたデバイスを選択してください。EtcherなどのGUIツールを使っても良いでしょう。

あとはDIPスイッチをSDカードブートに設定し、microSDカードを接続して電源を入れるだけです。

U-Boot SPL 2024.01+dfsg-1ubuntu5 (Apr 04 2024 - 16:22:45 +0000)
DDR version: dc2e84f0.
Trying to boot from MMC2

(中略)

U-Boot 2024.01+dfsg-1ubuntu5 (Apr 04 2024 - 16:22:45 +0000)

CPU:   rv64imafdc_zba_zbb
Model: Milk-V Mars
DRAM:  8 GiB
Core:  132 devices, 26 uclasses, devicetree: board
WDT:   Not starting watchdog@13070000
MMC:   mmc@16010000: 0, mmc@16020000: 1
Loading Environment from SPIFlash... SF: Detected gd25lq128 with page size 256 Bytes, erase size 4 KiB, total 16 MiB
(後略)

U-BootのSPL(Secondary Program Loader)と本体がUbuntu版となっています。このまま放っておけばUbuntuが起動しますので、ユーザー名「ubuntu⁠⁠、パスワード「ubuntu」でログインしてください。初回ログイン時はパスワードの変更が要求されます。

Ubuntu 24.04 LTS ubuntu ttyS0

ubuntu login: ubuntu
Password: ubuntu
You are required to change your password immediately (administrator enforced).
Changing password for ubuntu.
Current password: ubuntu
New password:
Retype new password:

これでプレインストールイメージのインストールは完了です。

プレインストールイメージからブートローダーを更新

次にLiveインストーラーのためにプレインストールイメージを使って、SPI Flash上のブートローダーを更新しましょう。これはU-Bootから行いますので、一度Milk-V Marsの電源を切って再起動します。U-Bootのログが流れ出したら、Enterキーを入力し続けてください。Hit any key to stop autoboot:と表示されたタイミングでStarFilve #のようなU-Bootのプロンプトになるはずです。

あとは次の手順で、microSDカード上のブートローダーをSPI Flashに書き込みます。

Hit any key to stop autoboot:  0
StarFive # sf probe
SF: Detected gd25lq128 with page size 256 Bytes, erase size 4 KiB, total 16 MiB

StarFive # load mmc 1:1 $kernel_addr_r /usr/lib/u-boot/starfive_visionfive2/u-boot-spl.bin.normal.out
141935 bytes read in 23 ms (5.9 MiB/s)
StarFive # sf update $kernel_addr_r 0 $filesize
device 0 offset 0x0, size 0x22a6f
141935 bytes written, 0 bytes skipped in 0.687s, speed 210639 B/s

StarFive # load mmc 1:1 $kernel_addr_r /usr/lib/u-boot/starfive_visionfive2/u-boot.itb
1041691 bytes read in 78 ms (12.7 MiB/s)
StarFive # sf update $kernel_addr_r 0x100000 $filesize
device 0 offset 0x100000, size 0xfe51b
963867 bytes written, 77824 bytes skipped in 7.207s, speed 147925 B/s

sf probeでSPI Flashを検知し、load mmcでmicroSDカード上の指定したファームウェアをメモリにロードします。最後にsf updateでメモリのデータをSPI Flash上に書き込んだら更新完了です。上記ではU-Boot SPLと本体の2回分更新しています。それぞれ書き込み先のアドレスやファイル名が異なる点に注意してください。

これでUbuntuのLiveインストーラーを使えるようになりました。

LiveインストラーでUbuntuをインストール

それではLiveインストーラーを使ってUbuntuをインストールしましょう。プレインストールイメージに対するLiveインストーラーの利点は次のとおりです。

  • 普通のサーバー版Ubutnuと同じインターフェースでインストールできる
  • パーティションレイアウトを自由にカスタマイズできる
  • 初期ユーザー・パスワードを自由にカスタマイズできる
  • ネットワーク設定を自由にカスタマイズできる
  • インストールを自動化できる

要するにLiveインストーラーの機能が使えるということです。ただしインストーラー用のストレージと、インストール先のストレージの両方を用意しなくてはなりません。今回はmicroSDカードにインストーラーを保存して、USB-SSDにUbuntuをインストールすることにします。

Liveインストーラーのイメージは、RISC-Vボードに依存せず共通です。

$ wget https://cdimage.ubuntu.com/releases/24.04/release/ubuntu-24.04-live-server-riscv64.img.gz
$ zcat ubuntu-24.04-live-server-riscv64.img.gz | sudo dd bs=1M conv=fsync status=progress of=デバイス

イメージの書き込み方法は、microSDと同じで「デバイス」部分を環境に応じて変更してください。もちろんこちらもEtcherなどのGUIツールを使ってもかまいません。

あとはDIPスイッチをSPI FLashに変更し、microSDとUSB-SSDをMilk-V Marsに接続して起動するだけです。Liveインストーラーを使う場合は、LANケーブルも接続しておくことをおすすめします[4]

起動後シリアルコンソールに次のようなエラーが表示された場合、SPI Flashの更新に失敗していることになります。その場合は「プレインストールイメージからブートローダーを更新」に戻って改めてインストールしなおしてください。

dwmci_s: Response Timeout.
Main section boot fail,use backup section
BOOT fail,Error is 0xffffffff

インストーラーが実際に起動するまで数分かかるので気長に待ちましょう。

図5 Liveインストーラーの場合はGRUBが起動する
図6 シリアルコンソールを接続していると画面レイアウトの確認が行われる

Ubuntuサーバーのインストーラーは、通常のディスプレイを前提に多少「見栄えの良く」表示しています。しなしながらこれをシリアルコンソールで行おうとすると、一部画面がうまく表示されない可能性があります。上記の画面では、シリアルコンソールからインストーラーにアクセスしている場合に、画面の表示をどうするかを問い合わせています。

  • 通常の画面を表示する(リッチモード)
  • ASCII文字だけを使う描画モードに変更する(ベーシックモード)
  • SSH経由でインストーラーを表示する

もしMilk-V Marsがネットワークに繋がっているのであれば、SSH経由の接続がおすすめです。この場合は、画面にアカウント名・IPアドレスと自動生成されたパスワードが表示されるため、それを用いてログインします。また、SSHを使わないのであれば、ベーシックモードを選ぶと良いでしょう。以降の画面はベーシックモードの内容を掲載しています。

図7 言語とキーボードの設定

ここから先は、Ubuntuサーバーのインストール画面と同じです。いくつかをかいつまんで紹介します。

図8 ネットワークインターフェースは「Unknown Vendor」と表示されるがきちんと動く
図9 ストレージはUSB-SSDデバイスを選択する。ここではI-O DATAのSSDがインストール対象だ
図10 ルートファイルシステムが100GiB固定になっているため、必要に応じて拡張しておく
図11 おすすめのsnapパッケージ一覧は空になっている

Ubuntuをインストールした経験があるなら、特につまづくところはないでしょう。ただしやはり性能的な都合で、インストール時間はだいぶかかります。実測としてカーネルのアップデート込みで15分ぐらいは必要でした。

Milk-V Mars上のUbuntu

インストールが完了したら再起動します。普通にGRUBが立ち上がって、見慣れたUbuntuのログイン画面になるはずです。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 24.04 LTS
Release:        24.04
Codename:       noble

lscpuや/proc/cpuinfoの結果は次のとおりです。SiFiveのU74コアが使われていることがわかります。

$ lscpu
Architecture:          riscv64
  Byte Order:          Little Endian
CPU(s):                4
  On-line CPU(s) list: 0-3
NUMA:
  NUMA node(s):        1
  NUMA node0 CPU(s):   0-3

$ cat /proc/cpuinfo
processor       : 0
hart            : 3
isa             : rv64imafdc_zicntr_zicsr_zifencei_zihpm_zba_zbb
mmu             : sv39
uarch           : sifive,u74-mc
mvendorid       : 0x489
marchid         : 0x8000000000000007
mimpid          : 0x4210427
hart isa        : rv64imafdc_zicntr_zicsr_zifencei_zihpm_zba_zbb

(後略)

ちなみに普通に動かしているだけで、CPUどころかUSBコネクターやRJ-45も触れなくなるくらい熱くなります。試しに何も冷却せずにCPUコアの温度を取得してみたら、81.5度(81506センチ度)ぐらいでした。本格的に運用するならヒートシンクやファンが必要になるでしょう。

$ cat /sys/class/hwmon/hwmon0/name
sfctemp
$ cat /sys/class/hwmon/hwmon0/temp1_input
81506

最後に第806回でも紹介した、sbc-benchを動かしてみます。これはシェルスクリプトをダウンロードして実行するだけです。必要なパッケージがインストールされて、ベンチマークを開始します。

$ git clone https://github.com/ThomasKaiser/sbc-bench.git
$ cd sbc-bench/
$ sudo ./sbc-bench.sh -c

Average load and/or CPU utilization too high (too much background activity). Waiting...

Too busy for benchmarking: 21:41:33 up 6 min,  1 user,  load average: 0.23, 0.13, 0.06,  cpu: 3%
Too busy for benchmarking: 21:41:38 up 6 min,  1 user,  load average: 0.21, 0.13, 0.06,  cpu: 0%
Too busy for benchmarking: 21:41:43 up 6 min,  1 user,  load average: 0.20, 0.13, 0.06,  cpu: 1%
Too busy for benchmarking: 21:41:49 up 6 min,  1 user,  load average: 0.18, 0.12, 0.06,  cpu: 0%
Too busy for benchmarking: 21:41:54 up 6 min,  1 user,  load average: 0.16, 0.12, 0.06,  cpu: 0%
Too busy for benchmarking: 21:41:59 up 6 min,  1 user,  load average: 0.15, 0.12, 0.06,  cpu: 0%

sbc-bench v0.9.67

Installing needed tools: apt-get -f -qq -y install gcc make build-essential lm-sensors links, p7zip 16.02, tinymembench, ramlat, mhz, cpufetch (can't build cpuminer) Done.
Checking cpufreq OPP. Done (results will be available in 10-16 minutes).
Executing tinymembench. Done.
Executing RAM latency tester. Done.
Executing OpenSSL benchmark. Done.
Executing 7-zip benchmark. Done.
(/usr/local/src/cpuminer-multi/cpuminer missing or not executable). Done.
Checking cpufreq OPP again. Done (12 minutes elapsed).

Results validation:

  * Measured clockspeed not lower than advertised max CPU clockspeed
  * No swapping
  * Background activity (%system) OK
  * Throttling occured -> https://tinyurl.com/4ky59sys

Memory performance
memcpy: 792.0 MB/s
memset: 753.0 MB/s

7-zip total scores (3 consecutive runs): 3934,3696,3733, single-threaded: 1124

OpenSSL results:
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes  16384 bytes
aes-128-cbc      22032.16k    27925.87k    29965.82k    30523.05k    30687.23k    30659.93k
aes-128-cbc      22041.57k    27911.45k    29965.91k    30531.93k    30689.96k    30681.77k
aes-192-cbc      20056.58k    24773.82k    26396.07k    26828.46k    26954.41k    26935.30k
aes-192-cbc      20042.81k    24777.90k    26391.72k    26828.46k    26962.60k    26929.83k
aes-256-cbc      18377.76k    22294.55k    23585.88k    23931.90k    24035.33k    24018.94k
aes-256-cbc      18321.32k    22266.01k    23577.77k    23924.05k    24032.60k    24018.94k

Full results uploaded to https://0x0.st/Xynn.bin

第806回までの結果と比較すると次のとおりです。

Device Clock Kernel 7-zip multi/single AES memcpy memset
RasPi 3B+ 1.4GHz 4.14 3240/914 36600 1130 1530
RasPi 4 1.8GHz 5.10 5790/1769 36260 2330 3120
VF2 Debian 1.5GHz 5.15 4090/1194 6820 860 760
VF2 24.04 1.5GHz 6.5 3930/1119 24020 790 750
Mars 1.5GHz 6.8 3790/1124 24020 790 750

当然のことながらSoCがVisionFive 2と同じではあるため、CPUの性能だけ見るとほぼ結果は同じです。ただ一部サーマルスロットリングが動いているために少し悪くなっているくらいでしょうか。

現時点でMilk-V Marsには、他のSBCに比べて強いメリットがあるわけではありません。日本から購入するのは大変ですし、何か尖った機能もありません。あえてあげるとすれば、M.2 E-KeyスロットでWi-Fi/Bluetoothボード等を拡張できる点はうれしいポイントではあるでしょう。しかしながらそのM.2 E-keyスロットもUbuntuのカーネルではまだうまく動かない状況です。

Milk-V Marsの真価はどちらかというとCompute Moduleのほうにあり、Marsはその評価用という位置づけと考えたほうが良さそうです。さらに今後も多数のRISC-Vマシンを開発しようとしているMilk-V製品をUbuntuでもサポートできるようになったという点において、Ubuntu的には重要なデバイスと言えるかもしれません。

おすすめ記事

記事・ニュース一覧