这是我的第一个问题:)
我目前正在编写一个通用的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不再支持卸载。 结果相同。
(我发现了几个使用OSKextRetainKextWithLoadTag
和OSKextReleaseKextWithLoadTag
的通用关键字示例
,但他们已经非常老了,并且不知道他们是否能够对抗最新版本的OS X.)
知道我做错了吗?
谢谢。
答案 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
中虽然因某种原因会保持加载状态。
所以你没有做错任何事,在某些版本中只是破解。