はじめに
私は普段、C# で業務アプリや静的アナライザーを作っている、いわゆる C# 屋です。
私の会社の代表は組込みのスペシャリストですが、私自身は組込みをこれから学ぶ立場にあります。
そこで、組込み Linux の勉強を始めました。
題材には、ARM と FPGA が1枚に載った DE1-SoC ボードを使います。
環境づくり
ボードで動かすカーネルモジュールは、Linux の上でクロスビルドします。
Linux を使うときは、これまで Windows の VirtualBox に Ubuntu を入れていました。
ところが今回は、この勉強に合わせて Mac(M4)デビューもしています。
組込みも Mac も初心者という、なかなか欲張りなスタートになりました。
macOS のままではカーネルのビルドが難しいので、仮想化ソフトの UTM で Linux の仮想マシンを作りました。
Linux の配布版には、Ubuntu(arm64 版)を使っています。
開発は、Windows を使わずに Mac だけで進めます。
Mac・Ubuntu・ボードの3つが、互いに通信できる状態を目指しました。
ところが、「Ubuntu からインターネットにもつながり、ボードとも通信できる」状態にするところで、さっそくつまずきました。
この記事では、仮想マシンに NIC を2枚付けて解決した方法をまとめます。
UTM や Ubuntu のインストール手順は、詳しい記事がほかにたくさんあるので省きます。
使った環境
| 項目 | 内容 |
|---|---|
| ホスト | Mac(Apple M4) |
| 仮想化ソフト | UTM(バックエンドは QEMU、方式は「仮想化」) |
| 仮想マシン | arm64(aarch64)、メモリ 4GB |
| 仮想マシンの OS | Ubuntu 20.04.3 LTS(arm64) |
| ボード | Terasic DE1-SoC(カーネル 5.10.50-altera) |
| 有線 LAN | LAN ポート付きの USB-C ハブ(LAN のチップは ASIX AX88179A) |
画面の項目名は、UTM 4.7.5 の日本語表示で確認しています。
なお、Ubuntu 20.04 の標準サポートは、2025年5月31日に終了しています(ログイン時のメッセージにも表示されます)。
これから環境を作る場合は、サポート中の版を選ぶことをおすすめします。
困ったこと:共有ネットワークだけでは、ボードと通信できない
UTM のネットワークは、初期設定では「共有ネットワーク」になっています。
このモードでは、Ubuntu は Mac を経由してインターネットに出られます。
しかし、最初は NIC が1枚(共有ネットワーク)のままで、ボードとの通信を試みて、うまくいきませんでした。
共有ネットワークでは、Ubuntu は Mac の中に作られた別のネットワーク(今回は 192.168.64.2)に置かれます。
そのため、LAN ケーブルの先のボードと同じセグメントにならず、直接やり取りできませんでした。
それでも、Ubuntu でビルドした .ko ファイルは、scp でボードに送る必要があります。
一方で、パッケージのインストールには、インターネットへの接続も欠かせません。
解決策:仮想 NIC を2枚にする
そこで、ボード用にブリッジの NIC を別に用意し、役割を分けて、Ubuntu に NIC を2枚付けました。
| Ubuntu での名前 | UTM のネットワークモード | 用途 |
|---|---|---|
enp0s1 |
共有ネットワーク | インターネット、Mac との通信 |
enp0s2 |
ブリッジ(詳細) | USB-C ハブの LAN ポートを指定して、ボードと同じネットワークにつなぐ |
UTM の設定
- Ubuntu を停止した状態で、UTM のサイドバーにある仮想マシン(今回は「Linux」)を右クリックして、メニューから「編集」を選びます。
- 設定画面の左側にある「デバイス」の一覧のいちばん下の「新規…」から、「ネットワーク」を1つ追加します。
- 追加したデバイスを、次のように設定して「保存」します。
| 項目 | 設定 |
|---|---|
| ネットワークモード | ブリッジ(詳細) |
| ブリッジインターフェイス | USB-C ハブの LAN ポート(今回の環境では en5) |
| 仮想ネットワークカード | virtio-net-pci |
1枚目のネットワーク(共有ネットワーク)は、そのまま残します。
追加したあとは、「デバイス」の一覧に「ネットワーク」が2つ並びます。
ブリッジインターフェイスの名前(en5 など)は、Mac や挿す場所によって違います。
ハブを挿した状態で、Mac のターミナルで次のコマンドを実行すると確かめられます。
networksetup -listallhardwareports
IP アドレスの設計
3つとも、同じセグメント(192.168.1.x)の固定 IP にしました。
| 機器 | IP アドレス |
|---|---|
| DE1-SoC | 192.168.1.10 |
| Mac(ハブの LAN ポート) | 192.168.1.11 |
Ubuntu(enp0s2) |
192.168.1.100 |
Mac は、最初は 192.168.1.1 にしていました。
しかし、ほかの機器とぶつかるのを避けるため、192.168.1.11 に変えました。
Ubuntu の IP を固定する(netplan)
最初に設定した IP が、再起動すると消えてしまいました。
そこで、/etc/netplan/ の設定ファイルに enp0s2 の固定 IP を書いて、再起動しても残るようにしました。
当時の設定ファイルは残っていないので、一般的な書き方の例を載せます(この記事のために動作を確かめたものではありません)。
/etc/netplan/ の中の .yaml ファイルに、次のように書きます。
ファイル名は、環境によって違います。
network:
version: 2
ethernets:
enp0s1:
dhcp4: true
enp0s2:
dhcp4: false
addresses:
- 192.168.1.100/24
enp0s1(共有ネットワーク)は DHCP のまま、enp0s2(ボード用)だけを固定 IP にしています。
enp0s2 には、ゲートウェイを書きません。
ゲートウェイを書くと、インターネットへの通信がボード側に流れてしまうおそれがあります。
設定を反映して、IP が付いたことを確かめるには、次のコマンドを実行します。
sudo netplan apply
ip addr show enp0s2
設定したあとは、Ubuntu にログインしたときのメッセージにも、2枚の NIC の IP が表示されます(実際の表示から抜粋)。
IPv4 address for enp0s1: 192.168.64.2
IPv4 address for enp0s2: 192.168.1.100
通信の確認
3つの経路で ping が通ることを確かめました。
| 送信元 → 宛先 | コマンド | 結果 |
|---|---|---|
| Mac → ボード | ping 192.168.1.10 |
応答あり |
| Mac → Ubuntu | ping 192.168.1.100 |
応答あり |
| Ubuntu → ボード | ping 192.168.1.10 |
応答あり |
つまずいたところ
LAN のハブを外すと、仮想マシンが起動しない
LAN ポート付きの USB-C ハブを Mac から外したまま、UTM で仮想マシンを起動したところ、次のエラーが出て、起動できなくなりました。
ハブを1つ外しただけで、仮想マシンごと動かなくなるとは思っていませんでした。
QEMU error: QEMUがエラーにより終了しました: qemu-aarch64-softmmu: -netdev vmnet-bridged,id=net1,ifname=en5: unsupported ifname 'en5', expected one of [ en0 ]
続けて「SPICE サーバへの接続試行中に内部エラーが発生しました。」とも表示されました。
これは、仮想マシンが起動しなかったために出た2つ目のエラーと考えられます。
原因は、1つ目のエラーにあります。
1つ目のエラーは、「ブリッジ先に指定した en5 が見つからない。ブリッジ先として選べるのは en0(Wi-Fi)だけ」という意味になります。
ブリッジ(詳細)は、Mac の実際のインターフェースを名前で指定します。
そのため、そのインターフェースがないと、仮想マシンそのものが起動できません。
次のどれかで直せます。
- ハブを挿し直してから起動する
- 挿す場所やハブを変えて、名前が変わった(
en6など)ときは、networksetup -listallhardwareportsで名前を確かめる。
そして、UTM の「ブリッジインターフェイス」を選び直す - ボードを使わないときは、2枚目のネットワークを UTM の設定で削除してから起動する
おわりに
NIC を役割ごとに分けたことで、ようやくインターネットとボードの両方につながるようになりました。
書いてしまえば数行の設定ですが、ここにたどり着くまでに何度かつまずきました。
LED を光らせる前に、まずネットワークで足止めされるのは、正直なところ予想外でした。
同じように Mac と UTM でボードにつなごうとしている方の、ヒントになればうれしいです。
思わぬ収穫
Windows から Mac に移ったことで、ターミナルでの操作が格段にしやすくなりました。
Mac のターミナルは、Linux と同じ感覚でコマンドを打てるので、Mac と Ubuntu とボードを行き来しても戸惑いません。
普段は Visual Studio にこもっている C# 屋が、今ではターミナルの快適さに感動しています。