3

这是我的第一个问题:)

我目前正在编写一个通用的 kext,它提供了一个字符设备并以 OSX 10.7+ 为目标。它是纯 C,IOKit/C++ 为零。(如果这很重要,我正在 10.11 上测试驱动程序。)

我希望在所有引用字符设备的文件描述符都关闭后卸载驱动程序,但这似乎不起作用。

根据Apple的文档OSKextRetainKextWithLoadTag

启用自动卸载后,在删除 kext 的最后一个引用后不久,如果没有对它的未完成引用并且没有其 Libkern C++ 子类的实例(如果有),它将被卸载。

...

定义 IOService 子类的 Kexts 会自动启用 autounload。其他 kexts 可以使用引用计数来管理自动卸载,而无需定义和创建 Libkern C++ 对象。

如上所述,我的 kext 没有任何子IOService类(或任何类,就此而言),所以我应该能够使用OSKextRetainKextWithLoadTag.

但是,在关闭所有文件描述符之后,kext 将永远保持加载:

static int cdev_open(dev_t dev, int flags, int devtype, struct proc *p)
{
    /* ... */

    return OSKextRetainKextWithLoadTag(OSKextGetCurrentLoadTag()) == kOSReturnSuccess) ? 0 : kOSReturnError
}

static int cdev_close(dev_t dev, int flags, int devtype, struct proc *p)
{
    /* ... */

   OSKextReleaseKextWithLoadTag(OSKextGetCurrentLoadTag());
   return 0;
}

此外,我编写了我的 kext 的“混合”版本,其中我使用提供IOService子类(IOResources作为提供者)的薄 C++ 包装器包装了启动和停止例程,以防通用 kext 不再支持卸载。结果相同

(我发现了几个使用OSKextRetainKextWithLoadTagand的通用 kext 示例OSKextReleaseKextWithLoadTag ,但它们非常旧,不知道它们是否适用于最新版本的 OS X。)

知道我做错了什么吗?

谢谢你。

4

1 回答 1

1

考虑以下generickext:

kern_return_t xxxKext_start(kmod_info_t * ki, void *d)
{
    // this should set auto unload enabled 
    // and retain a refcount on the kext
    OSKextRetainKextWithLoadTag(OSKextGetCurrentLoadTag());

    // this should call OSKext::considerUnloads()
    // and remove the search retain and the previous call retain
    OSKextReleaseKextWithLoadTag(OSKextGetCurrentLoadTag());

    // somewhere here or even before - kext suppose to be unloaded automatically (according to Apple docs)
    return KERN_SUCCESS;
}

kern_return_t xxxKext_stop(kmod_info_t *ki, void *d)
{
   return KERN_SUCCESS;
}

这个 kext 应该在很短的时间后自动消失,不管调用kextunload或类似的东西。

10.12.1它完美地工作。过了一会儿(不是他们在文档中描述的那么短的延迟),它将从kextstat命令中消失。

尽管由于10.11.6某种原因它会保持加载状态。

所以你没有做错任何事,它只是在某些版本中被破坏了。

于 2016-12-04T18:39:07.937 回答