IOKit驱动程序已加载但未启动

时间:2018-01-03 10:28:37

标签: c++ macos iokit kernel-extension xnu

我已经获得了非硬件触发的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>

但老实说,我不知道为什么,任何解释都会受到高度赞赏。

谢谢!

1 个答案:

答案 0 :(得分:0)

我只能猜测,因为您还没有提供完整的信息 - 特别是,您没有提供两位驱动程序的完整IOKit个性词典。

请注意,通常情况下,只有一项服务会成功匹配 IOService成为其客户端。如果您希望多种不同类型的客户端匹配,则需要通过个性词典中的IOMatchCategory键定义不同的匹配类别。许多驱动程序需要专门匹配IOResources,因此the rule for that case is to use the bundle identifier as match category。我怀疑这是你一直缺少的?

最后,关于使用默认发行版内核遇到问题的附注:内核调试工具包(KDK)提供了远程编译的备用开发调试内核不太激进的优化设置。您可能会发现它们很有用 - 请查看KDK的自述文档,了解有关如何启用它们的详细信息。