это мой первый вопрос здесь 🙂
В настоящее время я пишу общий kext, который предоставляет символьное устройство и предназначается для OSX 10.7+. Это чистый C, с нулевым IOKit / C ++. (В случае, если это имеет значение, я тестирую драйвер 10.11.)
Я хочу, чтобы драйвер был выгружен, как только все файловые дескрипторы, которые относятся к символьному устройству, закрыты, но, похоже, это не работает.
Согласно документации Apple для OSKextRetainKextWithLoadTag
:
Когда автозагрузка включена, то вскоре после удаления последней ссылки kext он будет выгружен, если на него нет выдающихся ссылок и нет экземпляров его подклассов Libkern C ++ (если таковые имеются).
…
Кекстам, которые определяют подклассы IOService, автоматически включается автозагрузка. Другие kexts могут использовать счетчик ссылок для управления автоматической выгрузкой без необходимости определять и создавать объекты Libkern C ++.
Как уже упоминалось выше, мой kext не имеет каких-либо IOService
подклассы (или любые классы, в этом отношении), поэтому я должен иметь возможность использовать OSKextRetainKextWithLoadTag
,
Однако kext остается загруженным навсегда, после того как все файловые дескрипторы закрыты:
static int cdev_open(dev_t dev, int flags, int devtype, struct proc *p)
{
/* ... */
return OSKextRetainKextWithLoadTag(OSKextGetCurrentLoadTag()) == kOSReturnSuccess) ? 0 : kOSReturnError
}
static int cdev_close(dev_t dev, int flags, int devtype, struct proc *p)
{
/* ... */
OSKextReleaseKextWithLoadTag(OSKextGetCurrentLoadTag());
return 0;
}
Кроме того, я написал «гибридную» версию своего kext, где я обернул процедуры запуска и остановки тонкой оболочкой C ++, которая обеспечивает IOService
подкласс (с IOResources
в качестве провайдера), в случае, если выгрузка больше не поддерживается с общими кексами. Тот же результат.
(Я нашел несколько примеров общих кексов, которые используют OSKextRetainKextWithLoadTag
а также OSKextReleaseKextWithLoadTag
, но они очень старые и не знают, работают ли они с последними версиями OS X.)
Есть идеи, что я делаю не так?
Спасибо.
Рассмотрим следующее generic
Kext:
kern_return_t xxxKext_start(kmod_info_t * ki, void *d)
{
// this should set auto unload enabled
// and retain a refcount on the kext
OSKextRetainKextWithLoadTag(OSKextGetCurrentLoadTag());
// this should call OSKext::considerUnloads()
// and remove the search retain and the previous call retain
OSKextReleaseKextWithLoadTag(OSKextGetCurrentLoadTag());
// somewhere here or even before - kext suppose to be unloaded automatically (according to Apple docs)
return KERN_SUCCESS;
}
kern_return_t xxxKext_stop(kmod_info_t *ki, void *d)
{
return KERN_SUCCESS;
}
Этот кекст должен автоматически исчезать через короткое время независимо от вызова kextunload
или что-то подобное.
в 10.12.1
это работает отлично. Через некоторое время (не так быстро, как они описывают в своих документах), оно исчезнет из kextstat
команда.
В 10.11.6
хотя по какой-то причине он останется загруженным.
Таким образом, вы не делаете ничего плохого, это просто сломанный в некоторых выпусках.
Других решений пока нет …