Каков Набор 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 поддерживает следующие функции:
Конфигурация динамического и автоматического устройства (Plug and Play)
Много новых типов устройств, включая графическое ускорение и мультимедийные устройства
Осуществление ядра защищенной памяти — разделяет адресные пространства для пользовательских программ и ядра
Общие абстракции совместно используются типами устройств
Улучшенный опыт разработки — новые драйверы должно быть просто записать
Набор I/O поддерживает эти функции ядра со своей новой моделью для драйверов устройств и добавляет некоторые дополнительные опции:
Объектно-ориентированная платформа, реализовывая общее поведение совместно использовала среди всех драйверов и типов (семейства) драйверов
Много семей для разработчиков для здания
Поточная обработка, коммуникация и примитивы управления данными для контакта с проблемами имели отношение к многопроцессорной обработке, управлению задачей и I/O-transfers
Устойчивый, эффективный механизм соответствия-и-загрузки, масштабирующийся хорошо ко всем типам шины
Реестр I/O, база данных, отслеживающая инстанцированные объекты (такие как экземпляры драйвера) и предоставляющая информацию о них
Каталог 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++, включая
Информация о типах во время выполнения (RTTI) — Набор I/O использует свою собственную реализацию системы типов во время выполнения
Эти функции были отброшены, потому что их считали неподходящими для использования в многопоточном ядре. Если Вы чувствуете, что Вам нужны эти функции, необходимо пересмотреть проект. Необходимо быть в состоянии записать любой драйвер, Вы требуете использования Набор 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. Код этих «библиотек» фактически встроен в ядро; однако, драйверы (когда загружено) действительно соединяются против ядра, как будто это была библиотека.
Платформа или библиотека | Описание и расположение |
---|---|
Kernel/IOKit | Библиотекой пользуются для разработки резидентных ядром драйверов устройств. Расположение заголовков: |
Kernel/libkern | Библиотека, содержащая классы, полезные для всей разработки программного обеспечения ядра. Расположение заголовков: |
Платформа используется для разработки интерфейсов устройства. Расположение: |
Приложения и инструменты
Вы используете ряд приложений разработки, чтобы создать, управлять, отладить, исследовать, и упаковать драйверы устройств. Таблица 1-2 перечисляет приложения, использованные в разработке драйвера; эти приложения установлены в /Developer/Applications
.
Таблица 1-3 описывает инструменты командной строки, используемые в разработке драйверов устройств с Набором I/O; все инструменты расположены в /usr/sbin/
или /sbin
.
Другие Ресурсы Набора 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 Аппаратные средства Из Приложений для полного обсуждения этой технологии.