kext隐藏在10.7卸载失败但10.6工作完美无缺

时间:2012-12-04 16:00:50

标签: usb hid iokit kernel-extension

我正在开发一个用于MacOSX的虚拟USB总线驱动程序(Windows已经运行)通过网络连接到Linux机箱。使用大容量存储设备和HID设备(如鼠标或键盘),它在10.6和10.7下工作正常。

但是,对于HID设备,删除设备(拔出)或更简单地卸载kext会失败 在10.7(.5)之下因为剩下的一个实例(分离后保留计数不会降到零)。 我的10.6和10.7测试环境与MacBooksPro 8.2 i7相同。

有时一段时间后(5-50分钟)kext变得自由,没有我身边的动作。 它似乎不依赖于不断变化的电源模式。

是的,我有USBFamily日志记录库和大量输出,但在工作(kextunload ok)和不工作运行之间我发现记录没有区别,即使记录级别为7。

由于大容量存储设备似乎运行良好,我猜问题是在HID驱动程序堆栈内特别是在10.7以下?

在10.6和10.7之间移除USB HID设备驱动程序堆栈是否有任何已知的差异?

我的kext是一个(虚拟)ControllerV3派生类,用于为任何真正插入的(在远程linux盒子)USB设备上建立/创建USBDevice。使用XCode 4.4.1。

提前感谢任何想法或提示, 问候    马库斯

PS:看起来有点奇怪,在10.7以下这么多的HID对象都在驱动程序堆栈之上。在kextunload(失败“.VirDevice有1个实例”)之后,它们似乎还活着。但这与100%相同的本地插入和拔出的罗技鼠标相同。

对我而言,只有最低的两个对象MsVirBus(虚拟USB总线,派生自IOUSBControllerV3)和Mouse @ xaffe003f with是一个IOUSBDevice派生对象。

Driver Stack after kextunload

1 个答案:

答案 0 :(得分:2)

我对HID堆栈没有丰富的经验,但我可以给你一些关于如何追查这类问题来源的一般IOKit / kext建议。

kextunload在I / O注册表中的所有对象上调用terminate()。这意味着有两种情况可能导致您无法卸载kext:

  1. terminate()失败或无法删除所有子对象

  2. 其余的活动对象都不在I / O注册表中

  3. 使用ioreg命令检查您的任何对象是否仍保留在I / O注册表中。还要检查他们拥有哪些客户端,因为这些客户端通常会阻止删除。

    如果注册表中没有您的对象,则很可能会出现保留/释放不匹配的情况。我提供了关于跟踪这些in this answer的一些建议,所以我在此不再重复。它似乎也不太可能,因为你的kext最终会卸载并在10.6上运行。

    如果您在I / O注册表中留下了对象,则需要追踪这些对象仍然存在的原因。如果您尚未在类中覆盖terminate(),请添加虚拟覆盖,只需将调用转发给基类实现。但是使用日志输出包装该转发调用,并输出调用是否成功。如果您已经覆盖terminate,请添加类似的日志记录。您可能还想为didTerminate()添加类似的日志记录,因为终止可以是异步的。

    拔下USB设备时,您应该将设备树中的terminate()传递给客户端。我会检查EHCI控制器代码的等效部分,看看是否需要任何特殊的参数等。