我正在为音频设备驱动程序(它是软件,但模拟硬件设备)编写 OSX 内核扩展。
在开发过程中,完全卸载现有的旧版本,然后从头开始构建和安装新版本会很方便。但是,如果不重新启动系统,这有时似乎是不可能的。
程序本身没有运行,源文件已从/System/Library/Extensions/
目录中删除。
但kextstat
揭示了一个例子:
$ kextstat | grep 'com.foo.driver.bar'
219 0 0xfff123 0x5000 0x5000 com.foo.driver.bar (0.0.1) <102 5 4 3>
(...意义:)
Index Refs Address Size Wired Name (Version) <Linked Against>
所以我的驱动程序实例有 0 个 Refs,但kextunload
有时会失败,抱怨现有实例:
$ sudo kextunload -b com.foo.driver.bar
(kernel) Can't unload kext com.foo.driver.bar; classes have instances:
(kernel) Kext com.foo.driver.bar class FooBarDriver has 1 instance.
(kernel) Kext com.foo.driver.bar class com_foo_driver_bar has 1 instance.
Failed to unload com.foo.driver.bar - (libkern/kext) kext is in use or retained (cannot unload).
发生这种情况时,无法“强制”卸载 kext(据我所知)。
由于正在运行的操作系统内核在内存中保存了一个引用,我猜测这个单一实例是否仍然存在?这似乎不对,因为kextunload
那样总是会失败。那么为什么kextunload
有时只需要重新启动系统才能“完全”卸载所有驱动程序实例呢?