自动卸载OS X驱动程序

时间:2016-09-19 08:29:19

标签: c++ c macos kernel-extension chardev

这是我的第一个问题:)

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

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

根据Apple的OSKextRetainKextWithLoadTag文档:

  

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

...

     

定义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;
}

另外,我写了" hybrid"我的kext版本,我用一个提供IOService子类(IOResources作为提供者)的瘦C ++包装器包装了启动和停止例程,以防通用kexts不再支持卸载。 结果相同

(我发现了几个使用OSKextRetainKextWithLoadTagOSKextReleaseKextWithLoadTag的通用关键字示例 ,但他们已经非常老了,并且不知道他们是否能够对抗最新版本的OS X.)

知道我做错了吗?

谢谢。

1 个答案:

答案 0 :(得分:1)

考虑以下generic kext:

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;
}

无论是调用kextunload还是类似的东西,此kext都会在短时间后自动消失。

10.12.1中的

完美无缺。过了一会儿(不是他们在文档中描述的短暂延迟),它将从kextstat命令中消失。

10.11.6中虽然因某种原因会保持加载状态。

所以你没有做错任何事,在某些版本中只是破解