MacOS设备驱动开发是否可以使用虚拟机代替物理机?

Can I use a virtual machine instead of a physical machine for MacOS device driver development?

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

经过深思熟虑,是否可以为此目的创建并 运行 虚拟机?具体来说,我可以让 OS X 来宾直接访问我的开发主机吗?

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

1.虚拟 Machine

中的 macOS kext development/testing/debugging

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

如果您将主机启动到 Linux,您还可以在 Qemu/KVM 虚拟机中 运行 macOS;内核调试也在那里工作。 (您也可以 运行 在 macOS 上的 Qemu 中使用它,但它只支持仿真模式,与硬件辅助虚拟化相比,速度慢得令人痛苦。)

2。虚拟机中的设备驱动程序 development/testing/debugging

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

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

  • USB 设备直通通常得到很好的支持。我已经提到的所有虚拟化环境都以某种形式支持这一点。对于某些类型的 USB 设备,它比其他类型的设备效果更好,并且不能通过一种 VM 系统正常工作的设备可能通过另一种 VM 系统工作得更好。然而,这种类型的直通发生在 USB 总线级别 - 主机控制器比这更深一层。
  • PCI(e) 设备直通原则上在现代硬件上也是可能的,如果许多组件聚集在一起的话。你需要:
    1. 具有活动硬件 IOMMU 的主机系统。 (I/O 内存管理单元)英特尔对此的实现称为 "VT-d"。 Macs 通常从 Intel 的 "Ivy Bridge" Core 系列 CPU 开始就有这个。 (Core i?-3??? 和更新版本)我相信一些较旧的 Mac Pros (Xeon) 也有此功能。与大多数 PC 不同,它在 Macs 的固件中默认启用。这是必需的,以便可以将客户物理内存地址透明地传递给设备以用于 DMA 目的——这些地址将与实际的主机物理内存页面地址不匹配,并且 IOMMU 可以在两者之间进行转换。如果没有这个,来宾 VM 可以发出 DMA read/writes 来托管它不拥有的内存!
    2. 主机操作系统支持 IOMMU。如果它可用,macOS 默认使用它,主要是为了抵御恶意 Thunderbolt 设备。它通常需要在 Linux 上通过内核命令行激活;不知道Windows.
    3. 上是什么情况
    4. 可以使用 IOMMU 将 PCI 设备直通到来宾的 VM 软件。
      • Qemu/KVM 可以通过 vfio[= 在 Linux hosts 上执行此操作60=](主机)内核模块。我对此有一些个人经验,包括 macOS 来宾;在许多情况下,它的效果出奇地好,即使使用某些 GPU 也是如此。
      • VMWare ESXi 显然也支持 PCI 直通。 (据说如果 ESXi 运行 在 Mac 硬件上运行,这包括对 macOS 来宾的支持)我个人对此设置没有经验。
      • macOS 主机上的常见桌面虚拟化环境(VMWare Fusion、Parallels Desktop、VirtualBox)据我所知不支持 PCI 直通。
      • done some research into the feasibility 支持从 macOS 主机到 xhyve/hyperkit VM 来宾的 PCI 直通。我想我知道该怎么做,但我还没有时间尝试实施它。 (也没有人付钱让我尝试)即使如此,您的用例还有两个障碍,即缺少模拟帧缓冲设备和 xhyve/hyperkit 中缺少 macOS 来宾支持。但是,只要有足够的开发人员资源,这两个问题都相对容易解决。

总结:

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

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