用 BHyVe 虚拟机解决 FreeBSD Wi-Fi 驱动的问题

• 本文约 1092 字,阅读大致需要 3 分钟 | Kernel | #FreeBSD | #Linux | #Wi-Fi | #BHyVe | #wifibox | #Virtualization | #Drivers | #Networking | #虚拟化

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直接安装。

网络方面,配置好之后大致的状态如下:

1
2
3
4
5
6
7
8
9
**********************************************
*                  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基本上不需要做什么配置,主要需要做的配置是:

  1. 禁用FreeBSD自带的驱动,并改为使用DHCP获得wifibox提供的IP。在 /etc/rc.conf 中加入:
        devmatch_blacklist="if_iwm if_iwlwifi"   # 根据实际情况自行调整
        ifconfig_wifibox0="DHCP"
        wifibox_enable="YES"
    并注释掉之前的Wi-Fi配置。
  1. 指定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

  1. /etc/wpa_supplicant.conf 的内容合并到 /usr/local/etc/wifibox/wpa_supplicant/wpa_supplicant.conf

总结

上述做法可以让FreeBSD直接连上802.11ac网络,目前未测试IPv6但大概率不行,不过还是希望iwlwifi尽早完工。