【问题标题】:Communicate with a driver - OS X与驱动程序通信 - OS X
【发布时间】:2014-07-19 08:25:08
【问题描述】:

给定一个非常简单的 IO 驱动:

class com_osxkernel_driver_IOKitTest : public IOService
{
    OSDeclareDefaultStructors(com_osxkernel_driver_IOKitTest)

    public:
        virtual bool init (OSDictionary* dictionary = nullptr);
        virtual void free(void);
        virtual IOService* probe (IOService* provider, SInt32* score);
        virtual bool start (IOService* provider);
        virtual void stop (IOService* provider);
};

这是 PLIST:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IOKitTest</key>
<dict>
    <key>CFBundleIdentifier</key>
    <string>com.osxkernel.${PRODUCT_NAME:rfc1034identifier}</string>
    <key>IOClass</key>
    <string>com_osxkernel_driver_IOKitTest</string>
    <key>IOMatchCategory</key>
    <string>com_osxkernel_driver_IOKitTest</string>
    <key>IOProviderClass</key>
    <string>IOResources</string>
    <key>IOResourceMatch</key>
    <string>IOKit</string>
</dict>

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
 <dict>
<key>com.apple.kpi.iokit</key>
<string>9.0.0</string>
<key>com.apple.kpi.libkern</key>
<string>9.0.0</string>
</dict>
 </plist>

驱动程序运行得非常好,我可以使用“内核日志”以及在键入时看到它:

kextstat | grep -v com.apple

问题是我不知道如何使用用户空间应用程序进行通信,我如何找到它? 我知道它与字典有关,我尝试使用以下代码找到它但没有运气(使用苹果开发者网站):

int search_driver ()
{
io_iterator_t iter = 0;
io_service_t service = 0;
kern_return_t kr;

CFDictionaryRef matchingDict = IOServiceMatching("IOResources");
kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter);
if (kr != KERN_SUCCESS) {
    printf("Nothing found. \n");
    return -1;
}
// Iterate over all matching objects.
while ((service = IOIteratorNext(iter)) != 0)
{
    CFStringRef     className;
    io_name_t       name;
    // List all IOUSBDevice objects, ignoring objects that subclass IOUSBDevice.
    className = IOObjectCopyClass(service);
    IORegistryEntryGetName(service, name);

    printf("Found device with name: %s\n", name);
    CFRelease(className);
    IOObjectRelease(service);
    // Release the iterator.
    IOObjectRelease(iter);
}
return 0;
}

我试过了:

CFDictionaryRef matchingDict = IOServiceMatching("IOResources");
CFDictionaryRef matchingDict = IOServiceMatching("IOService");

还有更多。

但仍然没有运气。第一个发现:IOResources 第二个发现:Macbook Air 5,2

我做错了什么?如何使用简单的用户空间应用程序找到正在运行的驱动程序并与之通信?

【问题讨论】:

    标签: macos kernel driver


    【解决方案1】:

    您的 IOKitTest 实现文件是什么样的?在该文件中,您需要通过调用 registerService() 来注册服务,以便客户端可以找到它。可以在启动函数中添加,例如:

    bool com_osxkernel_driver_IOKitTest::start (IOService *provider)
    {
        bool res = super::start(provider);
        super::registerService(); // <---- add this
        IOLog("IOKitTest::start\n");
        return res;
    }
    

    然后在您的 search_driver() 函数中,您可以查找您的确切类而不是 IOResources 小块。

    matchingDict = IOServiceMatching("com_osxkernel_driver_IOKitTest");
    

    周围有一些较旧的文档,其中包含这些函数的示例,而没有 registerService() 调用,这在较新的系统上不起作用。如果这能解决您的问题,请告诉我。

    【讨论】:

    • 嗨!我知道它有点老了,但我面临着同样的问题。我试过打电话给registerService(),但没有成功。有任何想法吗?谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-28
    • 2012-11-29
    • 1970-01-01
    • 2013-03-23
    • 2020-07-18
    • 2013-01-17
    相关资源
    最近更新 更多