У меня есть базовый драйвер 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).
Более того, через некоторое время создается впечатление, что вышестоящий драйвер просто удаляется из загруженных кекстов (вероятно, из-за бездействия) ..
Является ли мой дизайн законным или мне также нужно изменить 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>
но я честно не знаю почему, любое объяснение будет высоко оценено.
Спасибо !
Я могу только догадываться, потому что вы еще не предоставили полную информацию — в частности, вы не предоставили полные словари IOKit для ваших двух водителей.
Обратите внимание, что обычно только один сервис будет успешно матч IOService
стать его клиентом. Если вы хотите, чтобы несколько разных типов клиентов соответствовали, им нужно определить различные категории соответствия сквозь IOMatchCategory
ключ в словаре личности. Многие водители должны соответствовать IOResources
именно так правило для этого случая должно использовать идентификатор пакета как категорию соответствия. Я подозреваю, что это то, что вы пропустили?
Наконец, что касается вашего замечания о проблемах с выпусками ядра по умолчанию: комплекты отладки ядра (KDK) предоставляют альтернативные развитие а также отлаживать ядра, которые скомпилированы с гораздо менее агрессивными настройками оптимизации. Вы можете найти их полезными — ознакомьтесь с документацией readme KDK, чтобы узнать, как их включить.
Других решений пока нет …