Анатомия расширения ядра

Kexts являются загружаемыми пакетами, и как все загружаемые пакеты, они загружаются динамично другим приложением. В случае kext это приложение является самим ядром. Это имеет много импликаций для kexts, таких как выполнение в привилегированном режиме и возможности загрузиться во время ранней начальной загрузки. Kexts имеют строгую безопасность и требования расположения, чтобы Вы следовали для своего kext для работы.

Для понимания анатомии kext у Вас должно быть основное понимание пакетов. Для получения общей информации о структуре пакета см. Руководство по программированию Пакета.

Пакет Kext обычно содержит два основных компонента

В наиболее общем случае пакет kext содержит два компонента: информационный список свойств и исполнимая программа. Вместе с этими компонентами пакет kext может включать дополнительные ресурсы и плагины. Каждый из этих компонентов описан здесь.

Информационный список свойств

kext’s Info.plist файл описывает содержание kext. Каждый kext должен иметь Info.plist файл. Поскольку kext может быть загружен во время ранней начальной загрузки, когда ограничено, обработка доступна, этот файл должен быть в формате XML и не может включать комментарии. Следующие ключи имеют особое значение в kext’s Info.plist файл:

  • CFBundleIdentifier используется для определения местоположения kext и на диске и в ядре. Многократный kexts с данным идентификатором может существовать на диске, но только один такой kext может быть загружен в ядре за один раз.

  • CFBundleExecutable указывает имя исполнимой программы Вашего kext, если это имеет тот.

  • CFBundleVersion указывает версию kext. Номера версий Kext следуют за строгим образцом (см. Свойства Info.plist для Расширений ядра).

  • OSBundleLibraries перечисляет библиотеки (которые являются kexts сами), против которого соединяется kext.

  • IOKitPersonalities используется драйвером Набора I/O для того, чтобы автоматически загрузить драйвер, когда он необходим.

Существуют несколько более kext-специфичные Info.plist ключи, позволяющие Вам далее описывать свой kext. Для полного обсуждения всего kext Info.plist ключи, включая ключи, относящиеся к специфичным для ядра средствам среды выполнения, видят Свойства Info.plist для Расширений ядра.

Исполнимая программа

Это - скомпилированный, исполняемый код Вашего kext. Ваша исполнимая программа ответственна за определение точек входа, позволяющих ядру загружать и разгружать kext. Эти точки входа отличаются в зависимости от шаблона Xcode, который Вы используете при создании kext. Таблица 1 описывает различия по умолчанию между двумя kext шаблонами XCode. Эта таблица предназначается для иллюстрирования только наиболее популярного способа использования каждого шаблона; ядро не дифференцируется между kexts, создаваемым с различными шаблонами, и возможно включить элементы обоих шаблонов в kext.

Таблица 1  сравнение двух шаблонов XCode для создания kext

Универсальный шаблон расширения ядра

Шаблон драйвера IOKit

Язык программирования

Обычно C

C++

Реализация

C функции зарегистрировался как обратные вызовы в соответствующих подсистемах

Подклассы одного или более классов драйвера Набора I/O, такой как IOGraphicsDevice

Точки входа

Запустите и остановите функции со связью C

C++ статические конструкторы и деструкторы

Загрузка поведения

Должен быть загружен явно

Загруженный автоматически Набором I/O при необходимости

Разгрузка поведения

Должен быть разгружен явно

Разгруженный автоматически Набором I/O после фиксированного интервала, когда больше не необходимый

Учебное руководство

Создание универсального расширения ядра с XCode

Создание драйвера устройства с XCode

Некоторые kexts не включают исполнимую программу. Эти kexts (названный codeless kexts) обычно используются, чтобы сказать Набору I/O использовать существующий драйвер для Вашего устройства. См. Соответствие Расширений ядра Codeless Новые Устройства к Существующим Драйверам для получения дополнительной информации.

Дополнительные ресурсы и плагины

Kexts иногда требуют дополнительных ресурсов, таких как встроенное микропрограммное обеспечение для устройства. Если Ваш kext требует ресурса, вставьте его Resources папка пакета Вашего kext. Если Вы планируете локализовать свои ресурсы, иметь в виду, что код пространства ядра не обнаруживает локализованные ресурсы. Код пространства пользователя действительно обнаруживает локализованные ресурсы в .lproj подпапки Resources папка, поэтому если к Вашему ресурсу получает доступ только код пространства пользователя, локализация, является прямой.

В дополнение к общим ресурсам kexts может содержать плагины, включая другой kexts. Если Ваш kext использует плагин, вставьте его PlugIns папка пакета Вашего kext. Удостоверьтесь, что плагин kexts не содержит плагин kexts собственный; только один уровень плагинов обнаруживается для ограничения обхода файловой системы во время ранней начальной загрузки.

Расширения ядра имеют строгие требования к защите

Kexts выполняются в пространстве ядра и выполнении в привилегированном режиме; следовательно, файлы и папки в пакете kext должны принадлежать root пользователь и wheel группа. Файлы должны иметь полномочия 0644, и папки должны иметь полномочия 0755. kext, которому не удается удовлетворить эти требования, не загрузится в ядро.

Во время разработки, чтобы гарантировать, что Ваш kext имеет надлежащее владение и полномочия, создают копию Вашего kext как пользователь root.

% sudo cp -R MyKext.kext /tmp
Password:

Этот метод требует создания новой копии kext каждый раз, когда Вы создаете его.

Расширения ядра Должны Находиться в/System/Library/Extensions

OS X ищет kext CFBundleIdentifier информационный ключ списка свойств. Kexts расположился в /System/Library/Extensions, и плагин kexts тех kexts, ищутся по умолчанию. Можно выполнить пользовательский поиск для определения местоположения kexts в других папках, но не рекомендуется этот подход. Если Ваш kext должен быть загружен во время загрузки начальной загрузки, он должен быть установлен в /System/Library/Extensions для операционной системы для определения местоположения его.

Соответствие расширений ядра Codeless новые устройства к существующим драйверам

codeless kext является пакетом kext, не содержащим исполнимую программу. codeless kext’s IOKitPersonalities словарь называет другие kexts, загружающиеся, когда индивидуальность соответствует на устройстве. Каждый из этих других kexts должен иметь исполнимую программу. Codeless kexts обычно используются с USB и устройствами HID, управляющимися от пространства пользователя. Поскольку драйвер ядра реализует стандартный протокол, он может использоваться почти всеми устройствами в этих категориях.

Например, большинство принтеров USB совместно использует универсальный драйвер, предоставленный Apple, AppleUSBMergeNub.kext. Apple не может включать соответствующий словарь для каждого принтера в этом kext, таким образом, можно установить codeless kext с индивидуальностью, соответствующей принтер и устанавливающей CFBundleIdentifier индивидуальности в com.apple.driver.AppleUSBMergeNub. Когда Ваш принтер присоединен к компьютеру, AppleUSBMergeNub.kext загружается для управления им. Перечисление 1 показывает пример словаря IOKitPersonalities такого codeless kext в формате XML.

Перечисление 1  IOKitPersonalities словарь codeless kext

<key>IOKitPersonalities</key>
<dict>
    <key>My_USB_Printer</key>
    <dict>
        <key>CFBundleIdentifier</key>
        <string>com.apple.driver.AppleUSBMergeNub</string>
        <key>IOClass</key>
        <string>AppleUSBMergeNub</string>
        <key>IOProviderClass</key>
        <string>IOUSBInterface</string>
        <key>idProduct</key>
        <integer>0000</integer>
        <key>idVendor</key>
        <integer>0000</integer>
    </dict>
</dict>