Каков Набор I/O?

Набор I/O является набором системных платформ, библиотек, инструментов и других ресурсов для создания драйверов устройств в OS X. Это основывается на модели объектно-ориентированного программирования, реализованной в ограниченной форме C++, опускающего функции, неподходящие для использования в многопоточном ядре. Путем моделирования аппаратных средств, подключенных к системе OS X и абстракции общей функциональности для устройств в определенных категориях, Набор I/O оптимизировал процесс разработки драйвера устройства.

Эта глава говорит о свойственных возможностях Набора I/O (и драйверов, разработанных с ним) о решениях, сообщающих его проекту, и о Наборе I/O, когда рассмотрено как продукт. Это также предлагает некоторые протесты и инструкции для тех, которые рассматривают разработку программного обеспечения ядра, таких как драйверы устройств.

Перед началом

Вы, возможно, разработали драйверы устройств для других платформ — Mac OS 9, возможно, или BSD или другая разновидность UNIX. Одна вещь Вы обнаружите чтение этого документа, состоит в том, насколько отличающийся подход с Набором I/O. Несмотря на то, что запись драйверов для OS X требует новых способов мышления и различных способов запрограммировать, Вы достаточно вознаграждены за смещение к этому новому подходу. Набор I/O упрощает разработку драйвера и поддерживает много категорий устройств. Как только Вы свалили основы Набора I/O, Вы сочтете его относительно простым и эффективным вопросом для создания драйверов устройств.

Перед попыткой разработки драйвера с Набором I/O Apple настоятельно рекомендует определенные предпосылки. Поскольку платформа использует модель объектно-ориентированного программирования, реализованную в ограниченном подмножестве C++, она помогает знать C++ или объектно-ориентированные понятия в целом. Кроме того, драйверы устройств не являются той же вещью как приложения, потому что, будучи резидентным объектом ядра, они должны соблюдать более строгие правила. Знание программирования ядра поэтому очень полезно.

Действительно, программированию в ядре обескураживают кроме тех случаев, когда это абсолютно необходимо. Много альтернатив для связи с аппаратными средствами и сетями существуют в более высоких уровнях системы, включая “функцию” интерфейса устройства I/O, Кит, описанный в Управляющих устройствах Извне Ядра, Видит, что действительно ли необходимо Программировать в Ядре? для больше на альтернативах программированию ядра.

Функции Набора I/O

От ее начала фундаментальная цель для Набора I/O состояла в том, чтобы разместить и увеличить собственные функции и возможности OS X, особенно те из среды ядра. Как модель драйвера для OS X, Набор I/O поддерживает следующие функции:

Набор I/O поддерживает эти функции ядра со своей новой моделью для драйверов устройств и добавляет некоторые дополнительные опции:

Модель объектно-ориентированного программирования Набора I/O реализована в ограниченном подмножестве C++. Объектная ориентация просто сам по себе является преимуществом в разработке драйвера из-за возможности многократного использования кода, которой это способствует. Как только Вы знакомы с Набором I/O, можно записать драйверы устройств намного более быстро и эффективно, чем Вы можете с помощью процедурной модели. Кроме того, возможность многократного использования кода уменьшает объем потребляемой памяти драйверов; драйверы, портированные от Mac OS 9, например, были до 75% меньшего размера в OS X.

Принципы разработки набора I/O

OS X является в основном продуктом двух деформаций технологии операционной системы: Mac OS 9 (и его предшественники) и BSD. Учитывая эту родословную, возможно, ожидала, что Apple примет модель драйвера устройства Mac OS 9 или FreeBSD. Вместо этого Apple принял решение перепроектировать модель. Несколько причин мотивировали это решение.

Во-первых, ни Mac OS 9 моделей драйвера, ни модель драйвера FreeBSD не предлагают ряд функций, достаточно богатых для удовлетворения потребностей OS X. Ядро OS X значительно более совершенствуется, чем его предшественники Mac OS; это обрабатывает защиту памяти, вытесняющую многозадачность, многопроцессорную обработку и другие функции, не существующие в предыдущих версиях Mac OS. Несмотря на то, что FreeBSD способен к обработке этих функций, модель BSD не предлагает другие функции, ожидаемые в современной операционной системе, включая автоматическую конфигурацию, укладку драйвера, управление питанием и динамическую загрузку устройств.

Таким образом основная мотивация позади Набора I/O была несоответствием в настоящее время доступных моделей драйвера. Модернизация архитектуры I/O должна была использовать в своих интересах и поддерживать функции операционной системы OS X. К этому концу разработчики Набора I/O рассчитались на модели объектно-ориентированного программирования, абстрагировавшей возможности ядра и аппаратные средства системы OS X и обеспечившей представление этой абстракции к верхним уровням операционной системы. Востребованная часть этой абстракции является реализацией поведения, характерного для всех драйверов устройств (или типы драйверов устройств) в классах Набора I/O.

Как пример, рассмотрите виртуальную память. В Mac OS 9, виртуальная память не является фундаментальной частью операционной системы; это - опция. Из-за этого разработчик должен всегда принимать виртуальную память во внимание при создании драйвера, и это повышает определенные сложности. Напротив, виртуальная память является свойственной возможностью OS X и не может быть выключена. Поскольку виртуальная память является основным принципом и принятой возможностью, знание его включено в системное программное обеспечение, и писатели драйвера не должны принимать его во внимание.

Набор I/O функционирует как своего рода основа и координатор для драйверов устройств. Это - отбытие от предыдущих моделей драйвера. В Mac OS 9, все комплекты разработчика программного обеспечения (SDKs) независимы друг от друга и копируют общую функциональность. OS X поставляет Набор I/O как часть единственного комплекта разработчика ядра (KDK); все части KDK опираются на общие основы. OS X помогает разработчикам использовать в своих интересах аппаратную сложность, не требуя, чтобы они закодировали сложность программного обеспечения в каждый новый драйвер устройства. В большинстве случаев они должны только добавить определенный код, делающий их драйверы отличающимися.

Другая часть принципов проектирования Набора I/O должна сделать проект абсолютно открытым. Вместо того, чтобы скрывать APIs в попытке защитить разработчиков от себя, весь исходный код Набора I/O доступен как часть Дарвина. Разработчики могут использовать исходный код в качестве средства разработке (и отладка) новые драйверы.

Ограничения набора I/O

Несмотря на то, что Набор I/O поддерживает большинство типов аппаратных средств в системе OS X, это не полностью поддерживает все аппаратные средства. Одна категория таких устройств - используемые для обработки изображений, среди них принтеры, сканеры и цифровые фотоаппараты. Набор I/O предоставляет только ограниченную поддержку этих устройств, обрабатывая связь с этими устройствами через семьи FireWire и USB. Приложения или другие программы в пространстве пользователя ответственны за управление представляющими параметрами этих устройств (см. Управляющие устройства Извне Ядра для подробных данных). Если Ваше приложение должно управлять устройством отображения, необходимо использовать надлежащий комплект разработчика программного обеспечения (SDK) обработки изображений.

Несмотря на то, что Набор I/O пытается представлять иерархию и динамические отношения среди устройств и служб в системе OS X, некоторые вещи являются трудными к краткому обзору. Именно в этих серых областях абстракции, такой, разделяя нарушения на уровни происходит, писатели драйвера более самостоятельно. Даже когда представление Набора I/O является чистым и точным, возможность многократного использования кода семейства Набора I/O может быть ограничена. Все аппаратные средства могут иметь свои собственные причуды, и водительский код должен принять эти причуды во внимание.

Выбор языка

Apple рассмотрел несколько языков программирования для Набора I/O и выбрал ограниченное подмножество C++.

C++ был выбран по нескольким причинам. Компилятор C++ зрел, и язык предоставляет поддержку для системного программирования. Кроме того, уже существует многочисленное сообщество Macintosh (и BSD) разработчики с опытом C++.

Ограниченное подмножество запрещает определенные функции C++, включая

Эти функции были отброшены, потому что их считали неподходящими для использования в многопоточном ядре. Если Вы чувствуете, что Вам нужны эти функции, необходимо пересмотреть проект. Необходимо быть в состоянии записать любой драйвер, Вы требуете использования Набор I/O с этими ограничениями на месте.

Используя Пространства имен в Драйвере Набора I/O

Обратите внимание на то, что можно использовать пространства имен в драйвере Набора I/O. Использование пространств имен может помочь Вам избежать коллизий имени и может сделать Ваш код проще читать и более удобный в сопровождении. Обязательно используйте формат обратного DNS для имени пространства имен (например, com.mycompany) избегать потенциальных конфликтов пространства имен.

Если Вы решаете использовать пространства имен в своем драйвере Набора I/O в ядре, не объявляйте подкласс OSObject в пространстве имен, или Ваш драйвер не загрузится. В настоящее время загрузчик не поддерживает OSObject-производные-классы, требующие квалификации, такой как один показанный ниже:

namespace com.mycompany {
    class com.mycompany.driver.myClass : public IOService { // This is not allowed.
        OSDeclareDefaultStructors (com.mycompany.driver.myClass);
    };
};

Используя статических конструкторов в драйвере набора I/O

В OS X v10.4, GCC 4.0 является компилятором по умолчанию для всех новых проектов, включая драйверы Набора I/O. В этом разделе описываются определенное различие между GCC 3.3 и GCC 4.0, который может влиять на совместимость Вашего в драйвере ядра между OS X v10.3.x и OS X v10.4.x. Для получения дополнительной информации о различиях между GCC 3.3 (компилятор по умолчанию в OS X v10.3) и GCC 4.0, включая портирование руководства, см., что GCC Портирует Руководство.

Если Вы выполняете статическую конструкцию в функции в C++ драйвер Набора I/O (или другой KEXT) скомпилированный с GCC 3.3 или ранее, знаете, что тот же KEXT, скомпилированный с GCC 4.0, больше не будет загружаться успешно. Это вызвано тем, что GCC 4.0 более строг о взятии, и выпуск привязывает среду ядра. При выполнении в функции статической конструкции в драйвере Набора I/O, скомпилированном с GCC 4.0 Вы будете, вероятно, видеть следующую ошибку, когда Вы попытаетесь загрузить его:

kld():Undefined symbols:
__cxa_guard_acquire
__cxa_guard_release

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

class com_mycompany_driver_mystaticclass;
void com_mycompany_driver_myclass::myfunction(void)
{
    static com_mycompany_driver_mystaticclass staticclass;
    staticclass.anotherfunction();
}

Можно избежать загружать ошибки путем изменения этого кода для предотвращения в функции статической конструкции, как в коде, показанном ниже:

class com_mycompany_driver_mystaticclass;
static com_mycompany_driver_mystaticclasss staticclass;
void com_mycompany_driver_myclass::myfunction(void)
{
    staticclass.anotherfunction();
}

Обратите внимание на то, что можно быть в состоянии избежать ошибок загрузки, связанных со статической конструкцией в функции, не изменяя код при компиляции KEXT с GCC 4.0 с помощью -fno-threadsafe-statics параметр компилятора, но это может привести к другим проблемам. В частности, если Вы не можете гарантировать, что потокобезопасность другими способами, компилируя Ваш KEXT с этой опцией может повредить Ваш код.

Части набора I/O

Физически и электронно, Набор I/O составлен из многих частей: платформы и библиотеки, средства разработки и инструменты тестирования и информационные ресурсы, такие как проекты в качестве примера, документация и заголовочные файлы. Этот раздел каталогизирует эти части и указывает, где они установлены и как к ним можно получить доступ.

Платформы и библиотеки

Набор I/O основывается на трех библиотеках C++. Все они упаковываются в платформах, но только IOKit.framework истинная платформа. Платформа Ядра существует прежде всего для представления заголовочных файлов ядра, включая те libkern и IOKit. Код этих «библиотек» фактически встроен в ядро; однако, драйверы (когда загружено) действительно соединяются против ядра, как будто это была библиотека.

Табличные 1-1  Платформы и библиотеки Набора I/O

Платформа или библиотека

Описание и расположение

Kernel/IOKit

Библиотекой пользуются для разработки резидентных ядром драйверов устройств. Расположение заголовков: Kernel.framework/Headers/IOKit

Kernel/libkern

Библиотека, содержащая классы, полезные для всей разработки программного обеспечения ядра. Расположение заголовков: Kernel.framework/Headers/libkern

IOKit

Платформа используется для разработки интерфейсов устройства. Расположение: IOKit.framework

Приложения и инструменты

Вы используете ряд приложений разработки, чтобы создать, управлять, отладить, исследовать, и упаковать драйверы устройств. Таблица 1-2 перечисляет приложения, использованные в разработке драйвера; эти приложения установлены в /Developer/Applications.

Табличные 1-2  Приложения используются в разработке драйвера

Приложение

Описание

XCode

Основное приложение разработки для OS X. XCode управляет проектами, обеспечивает полнофункциональный редактор кода, разрабатывает проекты согласно произвольно сложным правилам, обеспечивает пользовательский интерфейс для конфигурации программного обеспечения и действует как фронтэнд для поисков документации и отладки.

Проводник Реестра I/O

Включает графическое исследование содержания и структуру Реестра I/O.

Производитель пакета

Создает пакет установки для приложения Установщика; используемый для развертывания расширений ядра (включая драйверы устройств).

Таблица 1-3 описывает инструменты командной строки, используемые в разработке драйверов устройств с Набором I/O; все инструменты расположены в /usr/sbin/ или /sbin.

Табличные 1-3  инструменты Командной строки используются в разработке драйвера

Инструмент

Описание и расположение

ioreg

Распечатывает содержание Реестра I/O (версия командной строки приложения Проводника Реестра I/O).

kextload

Загружает расширение ядра (такое как драйвер устройства) или генерирует статически соединенный файл символов для удаленной отладки.

kextunload

Разгружает расширение ядра (если возможный).

kextstat

Статистика печати о в настоящее время загруженных драйверах и других расширениях ядра.

iostat

Ядро дисплеев статистика I/O по терминалу, диску и операциям CPU.

ioclasscount

Количество экземпляра дисплеев указанного класса.

ioalloccount

Дисплеи некоторый учет памяти, выделенной Набором I/O, возражают в ядре.

kextcache

Сжатия и расширения ядра архивов (включая драйверы), таким образом, они могут быть автоматически загружены в ядро во время начальной загрузки.

gcc

Версия Apple компилятора C++ GNU; XCode автоматически вызывает его с корректным набором флагов для проектов Набора I/O.

gdb

Версия Apple отладчика GNU; XCode автоматически вызывает его с корректным набором флагов для проектов Набора I/O.

Другие Ресурсы Набора I/O

Несколько информационных ресурсов включены с Набором I/O «продукт», особенно файлы документации и заголовочные файлы. Некоторые из этих ресурсов описаны в предыдущей главе, Введении в Основные принципы Набора I/O

Набор I/O является частью Дарвинского проекта Открытого исходного кода. Apple поддерживает веб-сайт, где можно счесть много информации связанным с Набором I/O и другими проектами С открытым исходным кодом управляемый Apple. Следующие два расположения особенно интересны:

  • Проекты С открытым исходным кодом — http://developer.apple.com/darwin/projects/

    Здесь можно найти ссылки к Дарвину и Дарвину, Передающему проекты потоком среди других проектов. Также обладавший ссылки к документации и инструментам.

  • Списки рассылки — http://developer.apple.com/darwin/mail.html

    Эти ссылки функций страницы, которые поместят Вас на Дарвинскую разработку и DarwinOS-пользовательские списки рассылки среди других.

Действительно ли необходимо ли программировать в ядре?

При размышлении о записи кода для среды ядра думайте тщательно. Программирование в ядре может быть трудной и опасной задачей. И часто существует способ выполнить то, что Вы хотите обойтись без касания ядра.

Программное обеспечение, находящееся в ядре, имеет тенденцию быть дорогим. Код ядра «соединен проводом» в физическую память и таким образом не может быть разбит на страницы системой виртуальной памяти. Поскольку больше кода помещается в ядро, меньше физической памяти доступно процессам пространства пользователя. Следовательно, действие разбивки на страницы, вероятно, усилится, таким образом ухудшая производительность системы.

Код ядра также по сути дестабилизирует, намного больше, чем код приложения. Среда ядра является единственным процессом, и это означает, что нет никакой защиты памяти между Вашим драйвером и чем-либо еще в ядре. Память доступа в неправильном месте и всей системе может прекратить работу, жертва паники ядра.

Кроме того, потому что код ядра обычно предоставляет услуги многочисленным клиентам пространства пользователя, любая неэффективность в коде может быть распространена тем клиентам, таким образом влияя на систему глобально.

Наконец, программное обеспечение ядра является реальной болью для записи. Существует тонкость для сцеплений, которые неизвестны в области разработки приложений. И ошибки в коде ядра более трудно найти, чем в программном обеспечении пространства пользователя.

Со всем этим в памяти, сообщение ясно. Это находится в общих интересах поместить как можно меньше код в ядро. И любой код, заканчивающийся в ядре, должен быть заточен и строго протестирован.

Когда код должен находиться в ядре

Ряд варранта ситуаций, загружающего драйвер или расширение в среду ядра:

  • Программное обеспечение используется самой средой ядра.

  • Программы пространства пользователя будут часто использовать программное обеспечение.

  • Программное обеспечение должно непосредственно реагировать на основные прерывания (поставленные контроллером прерываний CPU's).

Если программное обеспечение, которое Вы пишете, не соответствует ни одного из этих критериев, оно, вероятно, не принадлежит ядра. Если Ваше программное обеспечение является драйвером для диска, сетевого контроллера или клавиатуры, оно должно находиться в ядре. Если это - расширение файловой системы, это должно жить в ядре. Если с другой стороны это используется только время от времени единственной программой пространства пользователя, это должно быть загружено программой и находиться в нем. Драйверы для принтеров и сканеров попадают в эту последнюю категорию.

Альтернативы резидентному ядром коду

Apple обеспечивает много технологий, которые могли бы позволить Вам выполнить то, что Вы хотите сделать и остаться вне ядра. Сначала высокоуровневый APIs, предоставляющий Вам некоторый доступ аппаратного уровня. Например, Откройте, Transport является мощным ресурсом для многих сетевых возможностей, и Кварцевый Наборщик позволяет Вам сделать некоторые довольно низкоуровневые вещи с графической подсистемой.

Во-вторых, и столь же важный, интерфейсная устройством технология платформы Набора I/O. Через сменную архитектуру эта технология позволяет Вашему приложению взаимодействовать с ядром для доступа к аппаратным средствам. Кроме того, Вы можете — с небольшой справкой от Набора I/O — используют POSIX APIs для доступа последовательный, хранение или сетевые устройства. Посмотрите Управляющие устройства Извне Ядра для сводки интерфейсов устройства и посмотрите documentAccessing Аппаратные средства Из Приложений для полного обсуждения этой технологии.