我有非硬件触发的IOKit基本驱动程序,并且源自IOResources。它还使用IOServiceOpen
提供给用户空间客户端类,但我认为它与我的问题无关......主驱动程序具有IOKit依赖性,如派生驱动程序Info.plist文件中所述:
<key>OSBundleLibraries</key>
<dict>
...
..
.
<key>com.derived.driver</key>
<string>1.0.0</string>
</dict>
另一个驱动程序(由com.derived.driver
标识)实现为通用内核扩展并存储在/Library/Extensions
中。
当我加载基本驱动程序时,派生自动加载。由于派生的驱动程序驻留在/Library/Extensions
中,因此在kextcache
触发派生驱动程序之前也可以加载它。
但是,当我将派生驱动程序从泛型转换为IOKit格式时它停止工作,因此现在两个驱动程序IOProviderClass
都是IOResources
。
似乎派生的驱动程序只是拒绝启动它是基于IOService的类,输出日志中没有错误的迹象(我使用调试器并看到它实际上达到IOService::probeCandidates
而不是IOService::startCandidate
。因为内核编译优化,我不能不要把我的手指放在准确的流量上。
当我查看kextstat
当前加载的驱动程序时,似乎两个驱动程序都已加载,但根据ioreg
,只有基本驱动程序有活动实例(我原以为两个驱动程序将共享同一个提供程序,即IOResources)。
而且,过了一段时间,似乎更高的驱动程序简单地从加载的kexts中移除(可能是由于空闲)。
我的设计看起来是合法的还是我还必须将基本驱动程序中的IOProviderClass
字段从IOResources
更改为派生的基于IOService的驱动程序类。
<key>IOKitPersonalities</key>
<dict>
<key>myDriver</key>
<dict>
<key>CFBundleIdentifier</key>
<string>com.base.driver</string>
<key>IOClass</key>
<string>com_base_driver</string>
<key>IOProviderClass</key>
<string>com_derived_driver</string>
编辑:我实际上做了它,它工作(所有实例已根据ioreg初始化)。
+-o com_derived_driver <class com_derived_driver, id 0x10000091f, registered, matched, active, busy 0 (804415 ms), retain 6>
+-o com_base_driver <class com_base_mng, id 0x100000920, registered, matched, active, busy 0 (0 ms), retain 9>
但我老实说不知道为什么,任何解释都会受到高度赞赏。
谢谢 !
我只能猜测,因为您还没有提供完整的信息 - 特别是,您没有提供两个驱动程序的完整IOKit个性词典。
请注意,通常,只有一个服务会成功匹配IOService
成为其客户端。如果您希望多种不同类型的客户端匹配,则需要通过个性词典中的IOMatchCategory
键定义不同的匹配类别。许多车手需要特别匹配IOResources
,所以the rule for that case is to use the bundle identifier as match category。我怀疑这是你错过的?
最后,关于使用默认发行版内核遇到问题的附注:内核调试工具包(KDK)提供了备用开发和调试内核,这些内核使用远不那么激进的优化设置进行编译。您可能会发现它们很有用 - 请查看KDK的自述文件,了解有关如何启用它们的详细信息。