That's Done!

thatsdone's (mostly technical) memorandum

[ja] Zephyr qemu notes


Zephyr ESP32 notesを書いたので、次はqemuのメモをダンプしていきます。

対象は以下の2つです。

  • qemu-system-x86_64
  • qemu-system-aarch64

...が、そのうち増えるかもしれません(笑)

話の発端

まず、私は数年前から単純にCPUを使いまくるテスト用(というか教育用?)のプログラム(mpmt)を作っています。

ここにおいてあります。

https://github.com/thatsdone/mpmt

取り扱う言語が30を超えたくらいからネタ切れ感がでてきていたのと、 AGLに絡みはじめてから 同じLinux Foundation配下のRTOSにZephyrをAGLのSDV Reference PFで使おうよという話、 つまり SoDeV プロジェクトに首をつっこみはじめてから、 当時者としてZephyrに興味を持つようになりました。

それで、言語やそのランタイムだけではなく、RTOSでもmpmtを動かしてみるか…と思い至ったというのが発端です。

mpmtのZephyr版は このあたり を見てみてください。

さて、以下気づきのメモを列挙していきますが。他の記事と同様に随時更新していきます。

ターゲット...というかボード指定?のやりかた

west build する際に -b に何を指定するか?という話です。

  • x86_64の場合
    • qemu_x86_64
  • ARM64の場合
    • qemu_kvm_arm64

以下、マニュアル。

  • x86/x86_64 qemu target board
    • https://docs.zephyrproject.org/latest/boards/qemu/x86/doc/index.html
  • ARM64 qemu target board
    • https://docs.zephyrproject.org/latest/boards/qemu/kvm_arm64/doc/index.html

できあがるバイナリ

west build -t run ではなく、qemu-system-xxx から直接実行したい…とか、libvirtで制御できるようにしたいという場合には気にする必要があります。

x86_64の場合

x86_64の場合、buildディレクトリの中にバイナリが2つできあがります。

一方はZephyrのメインプログラムでもう一方はloaderになります。 mpmtのZephyr版のREADMEに書いておきましたがこういう感じです。

  • kernel: zephyr-qemu-locore.elf
  • loader: zephyr-qemu-main.elf

aarch64の場合

こちらは一般的な組み込み用のボードと同じで1つだけです。 buildディレクトリの中にzephyr.binができあがります。

KVMの仮想化支援機能を使いたい

west からqemuに指定のパラメータを渡す方法があるのかもしれませんが、現状は未調査です。 ただ、qemu-system-x86_64等から直接起動する場合は普通に使えます。

Zephyrのqemu_x86_64 boardでvirtioを使いたい

使えます。 …が、2点ほどハマったのでメモ。(2025/12/31追記)

virtio関連デバイスのdts定義がない

...というか、実はzephyrのツリーに含まれているのですが、ZEPHYR_ROOT/boards/qemu/qemu_cortex_a53.dts に記述がある程度で、qemu_x86_64 や qemu_kvm_arm64 で使おうとすると overlay ファイルを作ってやる 必要があります。

これに何を参考にすればよいのか悩ましいのですが、 ZEPHYR_ROOT/tests/drivers/build_all/virtio/boards/qemu_x86_64.overlay がテストに使われているもので、virtio-pci/virtio-net-pci/virtio-console-pci/virtio-entropy まではこれで使えるようです。

私は自分のアプリの boards ディレクトリの下に上記をコピーして持ってきてビルドできました。 (ただし、後述のprj.confの定義にも落とし穴がある)

CONFIG_UART_VIRTIO_CONSOLEが有効にならない?

prj.confで、以下の3つすべてを n に指定してやる必要があります。

  • CONFIG_EARLY_CONSOLE
  • CONFIG_X86_VERY_EARLY_CONSOLE
  • CONFIG_BOOT_BANNER

特に3つめは気づかなかったっすorz

今回は、比較的最近mergeされたらしい virtio-net のドライバを使い、qemu環境で動かそうとしていました。 参考までに prj.conf の差分を付けておきます。VIRTIO関連以外には、qemu環境なので、GPIOやLEDは無効にする必要がありました。

(venv) zephyr:~/zephyrproject/zephyr/samples/net/sockets/http_server$ git diff prj.conf
diff --git a/samples/net/sockets/http_server/prj.conf b/samples/net/sockets/http_server/prj.conf
index 5cfe2a04ad2..8b13bb6e150 100644
--- a/samples/net/sockets/http_server/prj.conf
+++ b/samples/net/sockets/http_server/prj.conf
@@ -26,6 +26,21 @@ CONFIG_NET_STATISTICS=y
 CONFIG_NET_STATISTICS_USER_API=y
 CONFIG_NET_LOG=y

+# for virtio_net
+CONFIG_PCIE=y
+CONFIG_ETH_DRIVER=y
+CONFIG_VIRTIO=y
+CONFIG_VIRTIO_PCI=y
+CONFIG_ETH_VIRTIO_NET=y
+
+CONFIG_PRINTK=y
+CONFIG_EARLY_CONSOLE=n
+CONFIG_BOOT_BANNER=n
+CONFIG_X86_VERY_EARLY_CONSOLE=n
+CONFIG_UART_VIRTIO_CONSOLE=y
+CONFIG_UART_VIRTIO_CONSOLE_F_MULTIPORT=y
+
+
 # JSON
 CONFIG_JSON_LIBRARY=y

@@ -64,8 +79,8 @@ CONFIG_NET_CONFIG_PEER_IPV6_ADDR="2001:db8::2"
 CONFIG_NET_TCP_TIME_WAIT_DELAY=0

 # Device drivers
-CONFIG_GPIO=y
-CONFIG_LED=y
+#CONFIG_GPIO=y
+#CONFIG_LED=y

 # Network debug config
 CONFIG_NET_SOCKETS_LOG_LEVEL_DBG=n

続きます。