是否可以使用虚拟机而不是物理机进行 MacOS 设备驱动程序开发



我想修改一个MacOS X USB XHCI控制器驱动程序。 根据Apple的说法,他们强烈建议使用两台机器的设置进行调试和测试。不幸的是,我的开发计算机具有目标硬件,而我无法访问另一台合适的计算机。

经过一番思考,是否可以为此目的创建和运行虚拟机? 具体来说,我是否可以让 OS X 客户机直接 IO 访问我的开发主机?

这里确实有几个问题,所以让我们解开各个部分:

1. 在虚拟机中进行 macOS kext 开发/测试/调试

这通常效果很好。如果将虚拟串行端口连接到 VM,则可以获取kprintf日志记录输出,并且根据模拟的以太网设备,可以附加 lldb 内核调试器会话。我知道这适用于VMWare Fusion和Parallels Desktop。我已经很多年没有使用VirtualBox了,但上次我尝试你必须使用virtio网络设备(和驱动程序),因为它模拟默认英特尔以太网适配器的方式似乎与OSX的驱动程序的内核调试支持不兼容。他们可能已经解决了这个问题。

如果将主机引导到 Linux,也可以在 Qemu/KVM 虚拟机中运行 macOS;内核调试同样适用于此。(您也可以在macOS上的Qemu中运行它,但这仅支持仿真模式,与硬件辅助虚拟化相比,该模式非常慢。

2. 在虚拟机中开发/测试/调试设备驱动程序

要么你正在为 VM 环境模拟的设备编写驱动程序 - 这种情况相当明显,当然你可以这样做。许多 VM 环境可以模拟 XHCI 主控制器。

但是,您询问的是有关对物理主机硬件的访问,这通常称为直通。这是否可行在很大程度上取决于虚拟化环境和设备类型:

  • USB设备直通通常得到良好支持。我已经提到的所有虚拟化环境都以某种形式支持这一点。它适用于某些类型的 USB 设备比其他类型更好,并且通过一个 VM 系统无法正常工作的设备可能通过另一个 VM 系统工作得更好。但是,这种类型的直通发生在USB总线级别 - 主控制器比这更深。
  • PCI(e)设备直通原则上也可以在现代硬件上实现,前提是多个组件组合在一起。你需要:
    1. 具有活动硬件 IOMMU 的主机系统。(I/O 内存管理单元)英特尔对此的实现称为"VT-d"。Mac通常从英特尔的"Ivy Bridge"酷睿系列CPU开始具有此功能。(Core i?-3???及更新版本)我相信一些较旧的Mac Pro(至强)也有此功能。与大多数PC不同,默认情况下在Mac上的固件中启用它。这是必需的,以便出于 DMA 目的,来宾物理内存地址可以透明地传递到设备 - 这些地址与实际的主机物理内存页面地址不匹配,IOMMU 可以在两者之间进行转换。否则,来宾虚拟机可能会向不属于它的主机内存发出 DMA 读/写!
    2. 默认情况下,macOS 会使用它(如果可用),主要用于防御恶意的雷雳设备。它通常需要通过 Linux 上的内核命令行激活;我不知道Windows上的情况如何。
    3. 可以使用 IOMMU 将 PCI 设备直通到来宾的 VM 软件。
      • Qemu/KVM可以通过vfio(主机)内核模块在Linux 主机上执行此操作。我对此有一些个人经验,包括 macOS 客人;在许多情况下,即使使用某些 GPU,它也能很好地工作。
      • VMWare ESXi显然也支持 PCI 直通。(假设如果 ESXi 在 Mac 硬件上运行,这包括对 macOS 客户机的支持)我对这种设置没有个人经验。
      • 据我所知,macOS主机上的常见桌面虚拟化环境(VMWare Fusion,Parallels Desktop,VirtualBox)不支持PCI直通。
      • 我已经对支持从macOS主机到xhyve/hyperkitVM来宾的PCI直通的可行性进行了一些研究。我想我知道该怎么做,但我还没有时间尝试实现它。(也没有😉人付钱让我尝试)即便如此,您的用例还有两个障碍是缺乏模拟帧缓冲设备和xhyve/hyperkit中缺乏macOS来宾支持。但是,如果有足够的开发人员资源,这两者都相对容易解决。

总结:

如果你想现在这样做,检查你的Mac是否有IOMMU,如果有,你似乎有两个选择:在上面启动Linux并使用Qemu/KVM,或者使用VMWare ESXi;在这两种情况下,创建一些macOS虚拟机(可能一个用于测试/调试,另一个用于开发/构建kexts)并使用vfio将要为其开发驱动程序的设备传递给测试VM。

这是否比使用两台Mac更方便是值得商榷的!

最新更新