用 BHyVe 虚拟机解决 FreeBSD Wi-Fi 驱动的问题
BHyVe
https://www.FreeBSD.org/ 10.0-RELEASE 起,系统提供了一个最早由 NetApp 开发的使用处理器提供的虚拟化硬件支持 (目前是 Intel VT 和 AMD-V;针对 ARM 平台的支持也在 https://reviews.freebsd.org/D26976) 的虚拟化环境 https://wiki.freebsd.org/bhyve,这套虚拟化环境可以运行支持 VirtIO 规范的各种操作系统,并提供了 UEFI 支持。
这套环境提供了 PCI 直通(passthrough) 能力。通俗地说,PCI 直通是直接把某个或某些原本应该由宿主(host) 管理的 PCI 总线上的硬件交给虚拟机(guest), 而非以虚拟化的方式由宿主系统代为管理的方式。 这样做的本意是绕过一层抽象来获得更好的性能,但有时也可以用来实现一些其他的目的。
FreeBSD 的 Wi-Fi 支持
FreeBSD 的 802.11 支持是 2003 年左右由 Sam Leffler 在引入 Atheros (现已被高通收购) 无线网卡支持时实现的。此后基于这套支持和公开文档,人们开发了一系列 Wi-Fi 驱动。 由于无线网络设备厂商已经在 Linux 驱动开发上进行了大量投资,目前 Linux 的 Wi-Fi 驱动较 FreeBSD 来说更为丰富。由于大部分此类驱动采取了 GPL / BSD 双许可证的授权, 因此比较理想的做法是实现 Linux 内核接口从而直接利用这些驱动,而不是从头重新开发一遍。
wifibox
考虑到已经有了虚拟化环境的支持,另一种可行的做法便是直接运行一个精简版的 Linux,用它来管理
Wi-Fi 硬件,然后通过 virtnet 来把网络接到 FreeBSD 上面来用。这样一来这个 Linux
虚拟机便实际上承担了驱动的角色。目前这种做法已经加入了 port (net/wifibox
) 并可通过 pkg
直接安装。
网络方面,配置好之后大致的状态如下:
**********************************************
* laptop *
* +---------+ +---------+ *
* | |10.2.0.2 10.2.0.1| | *
* | FreeBSD |<------------------>| wifibox |<*------> AP/router <--------> Internet
* | (host) | tap(4) | (guest) | *
* +---------+ +---------+ *
* *
**********************************************
在 wifibox 中运行的是一套 Linux 系统,在其中启用了路由功能,其 IP 地址是 10.2.0.1。 它会通过 DHCP 给宿主系统分配一个 IP(10.2.0.2)。
目前版本的 wifibox 是通过 grub-bhyve 启动的,其内部是一个 Alpine Linux 环境,日志通过 9p
直接放到宿主机的 /var/run/wifibox/appliance/
中便于观察其状态。
wifibox的配置
wifibox 基本上不需要做什么配置,主要需要做的配置是:
- 禁用 FreeBSD 自带的驱动,并改为使用 DHCP 获得 wifibox 提供的 IP。在
/etc/rc.conf
中加入:
devmatch_blacklist="if_iwm if_iwlwifi" # 根据实际情况自行调整
ifconfig_wifibox0="DHCP"
wifibox_enable="YES"
并注释掉之前的 Wi-Fi 配置。
- 指定PCI直通设备。这个设备可以用下面的命令获得:
pciconf -lv | grep -iB2 wireless | head -n 1 | cut -f1-4 -d: | \
sed -e 's,^.*@pci0:,,g' | tr : / | sed -e s,^,passthru=,g
上述命令会产生形似:
passthru=4/0/0
的输出(注意由于硬件的不同,4/0/0
可能是其他值),将其添加到 /usr/local/etc/wifibox/bhyve.conf
。
- 将
/etc/wpa_supplicant.conf
的内容合并到/usr/local/etc/wifibox/wpa_supplicant/wpa_supplicant.conf
。
总结
上述做法可以让 FreeBSD 直接连上 802.11ac 网络,目前未测试 IPv6 但大概率不行,不过还是希望 iwlwifi 尽早完工。