Table of Contents
* 理解齟齬や誤記があるかもしれませんが、ご容赦ください
*体力切れで結構な量の詳細を省いているかもです
1. 概要
今回のブログ投稿#1はFreeBSDのオーディオドライバー開発の開発環境構築について書きます。その前に、概要でオーディオドライバーを開発しようとする目的、目標、背景や開発環境の全体像について言及します。
1.1 目的
OSカーネル周りのドライバーを開発して実装力アップしたい
1.2 目標
Visionfive2 (RISC-V SBC) のFreeBSD PWMDACドライバーを実装して、Visionfive2 のイヤホンジャックからオーディオ出力をする
1.3 背景
OS領域の実装力アップを目的に、もとより興味があったLinux開発に携わりたいが参入障壁を高く感じ断念。開発スピードやOSとしての成熟度がLinuxと比較して低いFreeBSDなら俺でもいけるやろ!と思って開発開始。
1.4 開発環境の全体像
主な開発環境の構成要素は...
- 仮想ビルドマシン
- ホスト: x86_64 Arch Linux
- 仮想ビルドマシン: RISC-V 64 FreeBSD
- 検証ボード
- RISC-V 64 FreeBSD
開発環境の構成の漫画を書いてみました()
あくまでイメージなので実態とのズレはあるかもです。
基本的に開発環境で想定している開発・運用フローは以下👇️
- x86_64 Arch LinuxでQEMU仮想ビルドマシンを立てる
- QEMU仮想ビルドマシンでgitを使用してFreeBSDのソースコードを管理
- Arch LinuxでFreeBSDのオーディオドライバーを書く
- Arch Linuxから仮想ビルドマシンへオーディオドライバーをSCPで送信する
- QEMU仮想ビルドマシンでドライバーをビルドする
- ビルドしたドライバー(.koファイル)を検証用のvisionfive2ボードで動作確認
- SCPでビルドマシンからvisionfive2に送る
☝️以外にも、visionfive2の初期動作確認や異常事態のために UART to USB Converterを使ってホスト ↔ visionfive2を繋ぐ

2. 開発環境の構築
開発の前捌きをしていきます。
今回のドライバー開発をするには、2つの環境を構築する必要があります。
- (ビルド環境)ドライバーをビルドするためのビルドマシン
- (検証環境)ドライバーを検証するための検証ボード
2.1 ハードウェア前提
下記ハードウェアが前提になります。
| ホストマシン | x86_64 Arch Linux |
| 検証ボード | Visionfive2 (4GB model) |
2.2 仮想ビルドマシン
仮想ビルドマシンはこんな構成で構築していきます。
| OS | FreeBSD 15.1 STABLE |
| Platform | QEMU |
| Architecture | RISC-V |
| Host | x86_64 Arch Linux |
現時点、仮想環境のアーキテクチャはRISC-Vがオススメです。
仮想x86_64マシンでクロスコンパイルにチャレンジするのも選択肢ですが、デメリットがあります。以下に、メリット&デメリットの表👇️
| x86_64 | RISC-V | |
| pkgレポジトリ | ◎ |
✗ |
| kvm | ◎ | ✗ |
| ビルド適合性 | △ | ◎ |
- pkgレポジトリ
- x86_64
- とても充実している。開発ツールのインストールがサクサク
- RISC-V
- 公式レポジトリなし。gitなどはFreeBSDのportsからソースビルド
- x86_64
- kvm
- x86_64
- 仮想マシンとホストマシンのCPUアーキテクチャが同一なのでkvm使用可能
- RISC-V
- ホストマシンがx86_64なのでRISC-V仮想マシンでkvm使用不可
- x86_64
- ビルド適合性
- x86_64
- ドライバーのクロスコンパイル(x86_64 → RISC-V)設定が必要だが不明
- RISC-V
- クロスコンパイルの必要なしでRISC-Vターゲットのドライバーがビルドできる
- x86_64
x86_64はpkgの公式レポジトリが充実しているけどドライバーのクロスコンパイルの設定が出来ませんでした という感じです。
RISC-Vは公式レポジトリがないのでportsから開発ツールをソースビルドする羽目になります(gitすらソースビルドになるので骨が折れる)し、ビルド、コンパイルがx86_64と比較して遅かったです。
表にして出すと、QEMU x86_64の方がkvmも使えるのでビルドが早いだろうし便利そうなのでドライバーのクロスコンパイル方法さえ発見できれば乗り換えたい()
今回はビルド適合性が重要なのでQEMU RISC-Vを選択
2.2.1 QEMUインストール
Arch Linuxがホストとなって、QEMUで仮想ビルドマシンを走らせます。
なのでArch LinuxにQEMUをインストールしましょう。
$ sudo pacman -S qemu-full
QEMUで使用するブートローダー(u-boot)も必要になります。
以下コマンドでArch Linuxにインストールしましょう。
$ paru -S u-boot-qemu-bin
# installs at /usr/share/u-boot-qemu-bin/qemu-riscv64_smode/u-boot.bin
☝️paruはArch Linuxのユーザーコミュニティ管理レポジトリ群(AUR)にあるソフトをローカル管理するためのツールです。(インストール方法は各自ご確認ください...)
2.2.2 FreeBSD QCOW2ファイル
QEMUと一緒に使うQCOWファイルを調達します。
☝️を👇️のリンクからダウンロード
https://download.freebsd.org/snapshots/VM-IMAGES/15.1-STABLE/riscv64/Latest/
仮想マシンのベース(rootfs/kernelなど)になるファイルです。(よくわかってない)
書き込みを保持してくれるのでとても便利です。
2.2.3 ネットワークブリッジ
仮想マシンでコンパイルしたドライバーをSCPでVisionfive2に送信して、Visionfive2で検証&QAするので仮想マシンが外部ネットワークと接続できるようにネットワークブリッジをホストマシンの中で設定/作成します。以下にネットワークブリッジのイメージ図の漫画と設定手順を記載します。
イメージはこんな感じ👇️

設定手順は👇️
sudo nmcli con add type bridge ifname br0
sudo nmcli con add type bridge-slave ifname <ホストマシンのルーターにつながるインターフェイス> master br0
sudo nmcli con up br0
(nmcliがインストールできない場合は申し訳ありませんが別途手段をご検討ください.......)
2.2.4 仮想ビルドマシンの起動確認
必要なモノを揃えたので仮想ビルドマシンを以下コマンド起動させてみましょう。
起動コマンドの赤字箇所はqcow2イメージファイルがあるパスを指定してください。
qemu-system-riscv64 \
-M virt \
-smp 8 \
-m 8192 \
-nographic \
-bios default \
-kernel /usr/share/u-boot-qemu-bin/qemu-riscv64_smode/u-boot.bin \
-drive if=none,id=hd0,file=/opt/FreeBSD-build-machine/FreeBSD-15.1-STABLE-riscv-riscv64-zfs.qcow2,format=qcow2 \
-device virtio-blk-device,drive=hd0 \
-netdev bridge,br=br0,id=net0 \
-device virtio-net-device,netdev=net0

☝️のような画面がターミナルに表示されれば基本的に動作確認OKです。

2.2.5 portsのセットアップ
portsはツール(git, vimなど...)のgitレポジトリを一括管理するFreeBSDのシステム。Linux Distroで見る apt, pacman, dnfなど、ツールのバイナリをダウンロードするパッケージマネージャーと違い、gitのレポジトリをダウンロードしてソースからビルドする。
なぜportsが必要か → gitが必要だけどpkgでは提供されていないため
FreeBSDはpkgというパッケージマネージャーがあるが、RISC-VプラットフォームのFreeBSDはpkgがデータを取ってくるための公式レポジトリがない。今回はgitを使ってFreeBSDのソースコードを管理する予定。しかしpkg経由でgitのインストールは不可。
なのでports経由からgitをソースビルドする必要がある。
幸いなことにFreeBSDはfetchというツールが常備されているらしく、👇️のコマンドでportsの圧縮ファイルをダウンロードすることができる。
fetch -o /tmp/ports-main.zip https://github.com/freebsd/freebsd-ports/archive/refs/heads/main.zip
圧縮ファイルは以下パスで解凍する
unzip /tmp/ports-main.zip -d /usr/ports/
上記手順でportsのセットアップは完了です。
2.2.6 gitのソースビルド
【2.2.5でportsをセットアップすることが前提です】
👇️コマンドでgitのソースビルドをしましょう。
cd /usr/ports/devel/git && make install clean
ビルドは結構時間がかかりました(ハードや仮想環境依存ですが)。
2.3 検証ボード
まずは大前提のVisionfive2を準備しましょう。
amazonリンク👇️
2.3.1 Disk Imageの準備
👇️リンクを参考にvisionfive2用のOS imageを焼いたMicroSDカードを作りましょう。
FreeBSDのOS imageをMicroSDに焼いた後、OpenSBIとu-bootを差し替えるだけです。
(Linuxホスト上でfdiskを使う場合はリンクのコマンド通りにはいかないのでご注意)
2.3.2 検証ボードの動作確認
事前準備するモノ/こと
- UART to USB Converterを用意
- visionfive2とホストマシンを繋ぐためのデバイス(UART経由で)。ログを見たり、検証ボードのFreeBSDを操作するために必要なハードウェア
- (私はraspberrypi debug probeを流用してます)
- minicomをホストマシンにインストール
- ホストマシン側で走らせるプログラム。visionfive2からUART経由でログ見たり、visionfive2のFreeBSDを操作するために使用するホストマシン側のソフトウェア
2.3.1で作成したMicroSDカードをvisionfive2のスロットに差し込み、visionfive2のUARTピンをUART to USB Convertertに適切に接続し、ConverterのUSB側をホストマシンと繋ぎましょう。
ホストマシンがLinuxの場合はUART to USB Converterが/dev/ttyACM0みたいなデバイスファイル名でシステムに認知されます。
(👇️visionfive2 SBCの公式ドキュメントより引用)

👇️コマンドをローカル環境に合うように調整して走らせることでminicomを起動して待機させます。
sudo minicom -s
☝️コマンドを走らせた後にvisionfive2の電源を入れてブートログをホストマシン側でminicomから確認し正常に動作することを確認しましょう。

ログインまでたどり着けたら確認完了です。
2.4 visionfive2と仮想ビルドマシンのsshログインを有効化
SCPでファイル送信したり、ssh経由で仮想ビルドマシンとvisionfive2を操作したいのでsshログインを有効化します。
手順2.4.1と2.4.2を実施の上、それぞれのマシンのsshdを再起動してください。
2.4.1 /etc/ssh/sshd_configの変更
各マシンの /etc/ssh/sshd_config を編集して以下設定に変更を入れてください。
| 変更前 | 変更後 |
| #PermitRootLogin no | PermitRootLogin yes |
2.4.2 /etc/rc.confの変更
2.4.1の変更を完了したら次は /etc/rc.conf に以下を追加
sshd_enable="YES"
3. 次回
次回の#2投稿では「FreeBSDのドライバー周りの概念やJH7110のオーディオ関連ハードウェア」と「ドライバー実装」について書こうと思います。
書き切る体力があるか心配ですが頑張ります()
