2015-06-10 8 views
1

Часть моей работы в течение наименее лет - это USB-виртуализация под OSX, и я снова оказался в замешательстве перед закрытой дверью.OSX kext: Не удается открыть IOResouces в :: start() из-за того, что принадлежал какой-то другой

Один из первых шагов, который мой kext (полученный от IOUSBControllerV3), как сделать, после моего провайдера (IOResources, потому что я virtuall) называется my :: start() (:: init() done), внутри супер класс, чтобы попробовать провайдер-> открыть (это).

Это нормальный путь и прекрасно работает до дня, другая (не от меня) виртуализация kext уже загружена. Затем вызов завершился неудачно и, следовательно, my :: start(), и установка kext вообще не сработала (не работает).

Схватив исходный код класса IOService и получить от Информацию по provider-> IsOpen() верно и provider-> IsOpen (это) является ложным IOResouces, казалось, принадлежит другой (virtulisation) Kext. Это означает, что внутренний __owner IOService занят эксклюзивным каким-либо другим.

Как это может быть? Как IOResources могут обрабатывать только один __owner за один раз?

Звонок провайдера-> open() выполняется внутри моего базового класса IOUSBController :: start() и до сих пор остается открытым до тех пор, пока не будет выведено значение stop(), что означает конец жизни.

Ошибка отказа от поставщика вызова-> open (this) внутри моего суперкласса IOUSBController :: start() внутри my :: start() и зависит от того, загружен ли еще один kext с провайдером IOResources или нет.

В этом состоянии не может быть конфликтов между конфликтами, поскольку это начало загрузки kext. И в моем воображении не может быть никакого конфликта ресурсов вообще, потому что все это virtuall.

Или это правда, что IOResources могут обрабатывать (быть поставщиком для) один kext?

Нет, невероятно. Моя следующая идея заключалась в том, что foreigen kext плохо реализован (это не идеально, потому что kextunload невозможно), но вызовы provider-> open (this) и -> close (this) выполняются в базовых классах Holy Apple, который должен быть правильным.

Извините, много текста и спасибо за любой конструктивный комментарий.

ответ

1

Есть ли веская причина, почему вам нужно open() IOResources? Точка open() в контексте IOService s специально предназначена для предоставления эксклюзивного или, по крайней мере, зарезервированного доступа к ресурсам, которые не поддерживают произвольное количество клиентов. (например, на физическом устройстве обычно может быть только один загруженный драйвер). IOResources - это фиктивная служба, которая не предоставляет никаких функций, кроме механизма publishResource/resourceMatching. Я не знаю, почему вам нужно позвонить open().

Редактировать: Я пропустил, что звонок open() сделан суперклассом Apple, а не кодом афера. В этом случае, как и для любых базовых классов, которые имеют особые требования к объекту поставщика, я рекомендую написать собственный класс поставщика. Этот класс провайдера может быть клиентом IOResources, а драйвер с суетливым базовым классом может быть его клиентом.

+1

Привет, вызов provider-> open() не из моего источника, а внутри функции :: start (поставщик) моего суперкласса IOUSBCrontroller, который я должен вызвать. Как вы знаете, для производных классов с перегруженными базовыми методами вы должны вызвать метод суперкласса внутри вашей функции перегрузки. Вы правы, между открытыми (это) и закрытыми (это) у вас есть эксклюзивный доступ к IOService (__owner = this). То, что я ожидал, было экземпляром IOResources для раздвоенного или клонированного провайдера, но, похоже, для всех был один экземпляр? ... Часть II соответствует –

+1

... Поскольку реальная система USBController (поставщик - это класс PCI) использует ту же библиотеку, я ожидаю, что конфликт ресурсов будет только для физических ресурсов (pci, адреса шины, ...), но IOResource должен иметь возможность провести множество параллельных операций. Спасибо за ваш комментарий! –

+0

Ahhh, теперь я вижу. Вероятно, вам лучше всего создать фиктивный объект IOService для размещения между IOResources и подклассом USB-контроллера. Затем ваше фиктивное устройство может создать контроллер, и контроллер вызовет open() на манекене, а не на IOResources. – pmdj

1

Следующее Phils (pmdj) очень конструктивные предложения, он, очевидно, является членом apple kext IOKit olymp, простое улучшение, похоже, устраняет мою проблему.

В :: начале (поставщик) создать (OSTypeAlloc()) фиктивная IOService класс dumprov, делают dumprov-> Init() и dumprov-> заводится (поставщик), а затем вызвать мой суперкласс IOUSBController :: заводится (dumprov) с успехом :-)

Когда меня называют finaly to :: stop(), я вызываю IOUSBController :: stop (dumprov) и создаю dumprov-> release(). Отлично!

Большое спасибо pmdj !!

+0

Рад слышать, что вы его отсортировали! – pmdj