3

我有 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>

但老实说,我不知道为什么,任何解释将不胜感激。

谢谢 !

4

1 回答 1

0

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

请注意,通常只有一个服务会成功匹配一个IOService成为其客户端。如果您希望匹配多个不同类型的客户端,他们需要通过个性字典中的键定义不同的匹配类别。IOMatchCategory许多驱动程序需要IOResources专门匹配,因此这种情况的规则是使用捆绑标识符作为匹配类别。我怀疑这是你一直失踪的?

最后,关于您在使用默认发行版内核时遇到问题的旁注:内核调试工具包 (KDK) 提供了替代开发调试内核,这些内核是用不那么激进的优化设置编译的。您可能会发现它们很有帮助 - 查看 KDK 的自述文件以了解有关如何启用它们的详细信息。

于 2018-01-03T21:11:27.253 回答