【问题标题】:Programmatically "unplug and replug" a USB device to load new driver in OS X?以编程方式“拔出并重新插入”USB 设备以在 OS X 中加载新驱动程序?
【发布时间】:2026-02-07 19:00:01
【问题描述】:

我正在使用 OS X 中的安装程序来为 USB 设备安装 IOKit 驱动程序,并且我正在尝试让它不需要在最后重新启动。安装程序正确安装驱动程序并重建kext缓存,运行后,如果我拔下USB设备并重新插入,它会正确加载新驱动程序,一切正常。

但是,我不想要求用户在物理上拔下设备以加载新驱动程序。必须有一种方法可以让 OS X 以编程方式加载新驱动程序 - 实际上模拟设备被拔出并重新插入,或类似的东西。我该怎么做呢?到目前为止,谷歌搜索数小时没有任何结果,因此我们将不胜感激!

【问题讨论】:

  • 我会尝试查看弹出 USB 大容量存储设备时运行的代码 — 我不确定是否存在相应的 USB 流量,或者它是否只是告诉 USB 子系统忽略端口直到物理拔掉。在前一种情况下(“USB 弹出”消息),除了电源循环或 USB 重置之外,可能没有简单的“取消弹出”方法,这两种方法都可能对其他 USB 设备造成问题。但希望这是开始寻找的地方。
  • 我读到了一个名为 pmount 的东西,它可以卸载更多任意 USB 设备,但我不知道这是否包括您的设备。唯一的大缺点是它默认不附带 OS X。
  • 我很确定您不能直接从用户空间执行此操作。但是,在内核中,您可以尝试在占用设备的现有客户端上调用 terminate()。

标签: macos installation usb driver iokit


【解决方案1】:

看看diskutil,尤其是mountunmount 选项。这些将以软件方式弹出和安装设备。您可以使用diskutil list 获取所有当前已安装设备的列表。如果您需要有关 diskutil 的更多信息,请查看手册页。

【讨论】:

  • 不幸的是,这个设备不是磁盘,它是一个人机界面设备,所以据我所知 diskutil 无济于事。
【解决方案2】:

IOUSBDeviceInterface187::USBDeviceReEnumerate() 会做你想做的事。唯一的障碍是找到所有感兴趣的设备并使用IOServiceGetMatchingServices()手动调用它们。

/*!
@function USBDeviceReEnumerate
@abstract   Tells the IOUSBFamily to reenumerate the device.
@discussion This function will send a terminate message to all clients of the IOUSBDevice (such as 
            IOUSBInterfaces and their drivers, as well as the current User Client), emulating an unplug 
            of the device. The IOUSBFamily will then enumerate the device as if it had just 
            been plugged in. This call should be used by clients wishing to take advantage 
            of the Device Firmware Update Class specification.  The device must be open to use this function. 
@availability This function is only available with IOUSBDeviceInterface187 and above.
@param      self Pointer to the IOUSBDeviceInterface.
@param      options A UInt32 reserved for future use. Ignored in current implementation. Set to zero.
@result     Returns kIOReturnSuccess if successful, kIOReturnNoDevice if there is no connection to an IOService,
            or kIOReturnNotOpen if the device is not open for exclusive access.
*/

IOReturn (*USBDeviceReEnumerate)(void *self, UInt32 options);

查看 IOKit/usb/IOUSBLib.h

【讨论】: