【问题标题】:IOServiceOpen returns kIOReturnUnsupported despite driver's user client instantiation尽管驱动程序的用户客户端实例化,IOServiceOpen 仍返回 kIOReturnUnsupported
【发布时间】:2017-01-06 01:04:43
【问题描述】:

我正在尝试编写一个非常简单的用户客户端 - 就目前而言 - 从用户空间写入内核日志。如果以下代码有效,它会将“Hello World”写入日志。

我已经验证我有正确的 IOService - com_soggywizards_Foo - 在下面的代码中调用 IOObjectGetClass。

IOServiceOpen 总是返回 kIOReturnUnsupported。但是,当它被调用时,我的用户客户端会出现在 IORegistryExplorer 中。我也可以在ioreg中看到它。

看起来 IOServiceOpen 正在实例化用户客户端,但在实例化完成之前返回其结果。

对 IOServiceOpen 的调用在“doOpen”函数中:

int main(int argc, const char * argv[]) {
CFMutableDictionaryRef  dict = NULL;

dict = IOServiceMatching( "com_soggywizards_Foo" );

kern_return_t result;
io_iterator_t it = NULL;

result = IOServiceGetMatchingServices( kIOMasterPortDefault,
                                                   (CFDictionaryRef)dict,
                                                   &it);

if ( result != KERN_SUCCESS ){

    fprintf( stderr, "IOServiceGetMatchingServices failed 0x%x\n", result );
    exit( 1 );
}

io_service_t service = IOIteratorNext( it );
if ( service == (io_service_t)NULL ){
    fprintf( stderr, "IOIteratorNext cant find service\n " );
    exit( 1 );
}

char name[ 256 ];

result = IOObjectGetClass( service, name );

cout << "service: " << name << endl;  // prints "service: com_soggywizards_Foo"

io_connect_t connect;

result = doOpen( service, &connect );

if ( result != KERN_SUCCESS ) return 1;

result = logMessage( "Hello World\n", connect );
if ( result != KERN_SUCCESS ) return 1;

return 0;

}

kern_return_t doOpen( io_service_t service, io_connect_t *connect )
{
kern_return_t result = IOServiceOpen( service, mach_task_self(), 0, connect );  // returns 0xe00002c7

if ( result != KERN_SUCCESS ) fprintf( stderr, "IOServiceOpen failed: 0x%x\n", result );
else{
    result = openUserClient( *connect );
    if ( result != KERN_SUCCESS ) fprintf( stderr, "openUserClient failed: 0x%x\n", result );
}

return result;

}

内核日志显示我的用户客户端的 initWithTask 被调用,并且 super::initWithTask 成功。还调用了我的用户客户端的启动方法。

我不清楚用户客户端是否需要致电registerService()。但是,ioreg 说它已注册,即使我不调用它。

【问题讨论】:

    标签: macos driver iokit kernel-extension


    【解决方案1】:

    您的驱动程序类或其除IOService 本身之外的超类之一是否覆盖newUserClient() 方法?如果超类覆盖它,并且您想添加额外的用户客户端类型,您也需要自己覆盖它。如果您已经覆盖它,则需要向我们展示它的代码,因为这很可能是您的问题所在。

    (通常,您的问题似乎是内核方面的,所以如果有疑问,请发布该代码。)

    关于registerService():如果您希望匹配您的IOService 对象,则需要调用此方法,并且它已准备好接受通过匹配找到的客户端 - 即由IOServiceGetMatchingServices() 或用户中的类似函数找到的,或者内核空间,包括 kext 的 IOKit 特性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-15
      • 2012-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      相关资源
      最近更新 更多