Обзор Набора I/O
Те из Вас, кто уже знаком с записью драйверов устройств для Mac OS 9 или для BSD, обнаружат, что запись драйверов для OS X требует некоторых новых способов мышления. В создании OS X Apple полностью перепроектировал Macintosh архитектура I/O, служа основой для упрощенной разработки драйвера, поддерживающей много категорий устройств. Эту платформу вызывают Набором I/O.
С точки зрения программирования Набор I/O обеспечивает абстрактное представление оборудования системы к верхним уровням OS X. Набор I/O использует модель объектно-ориентированного программирования, реализованную в ограниченном подмножестве C++ для продвижения увеличенного повторного использования кода.
Начиная с должным образом разработанных базовых классов, Вы получаете преимущество в записи нового драйвера; с большой частью кода драйвера, уже записанного, необходимо только заполнить определенный код, делающий драйвер отличающимся. Например, все контроллеры SCSI поставляют довольно стандартный набор команд к устройству, но делают так через различные низкоуровневые механизмы. Путем надлежащего использования методологии объектно-ориентированного программирования драйвер SCSI может реализовать те низкоуровневые транспортные части, не повторно реализовывая высокоуровневый код протокола SCSI. Подобные возможности для повторного использования кода могут быть найдены в большинстве типов драйверов.
Часть философии Набора I/O должна сделать проект абсолютно открытым. Вместо того, чтобы скрывать части API в попытке защитить разработчиков от себя, весь источник Набора I/O доступен как часть Дарвина. Можно использовать исходный код в качестве средства разработке (и отладка) новые драйверы.
Вместо того, чтобы скрыть интерфейсы, разработчики Apple приняли решение служить примером. Пример кода и классы показывают рекомендуемый (простой) способ записать драйвер. Однако Вам не препятствуют делать вещи твердый путь (или неправильный путь). Вместо этого внимание было сконцентрировано на создании «лучших» путей, простых следовать.
Перепроектирование модели I/O
Вы могли бы спросить, почему Apple принял решение перепроектировать модель I/O. На первый взгляд могло бы казаться, что многократное использование модели от Mac OS 9 или FreeBSD будет более простым выбором. Существует несколько причин решения, как бы то ни было.
Ни Mac OS 9 моделей драйвера, ни модель FreeBSD не предложили набор функций, достаточно богатый для удовлетворения потребностей OS X. Базовая технология операционной системы OS X очень отличается от того из Mac OS 9. Ядро OS X значительно более совершенствуется, чем предыдущая архитектура системы Mac OS; OS X должен обработать защиту памяти, вытеснение, многопроцессорную обработку и другие функции, не существующие (или существенно менее распространяющийся) в предыдущих версиях Mac OS.
Несмотря на то, что FreeBSD поддерживает эти функции, модель драйвера BSD не предлагала автоматическую конфигурацию, укладку, управление питанием или динамические загружающие устройство функции, требуемые в современной, ориентированной на потребителя операционной системе.
Путем перепроектирования архитектуры I/O инженеры Apple могут воспользоваться лучшим преимуществом функций операционной системы в OS X. Например, виртуальная память (VM) не является фундаментальной частью операционной системы в Mac OS 9. Таким образом каждый писатель драйвера должен знать о (и запись для) VM. Это представило определенные сложности для разработчиков. Напротив, OS X упростил взаимодействие драйвера с VM. Возможность VM свойственна от операционной системы OS X и не может быть выключена пользователем. Таким образом возможности VM могут быть абстрагированы в Набор I/O, и код для обработки VM не должен быть записан для каждого драйвера.
OS X предлагает беспрецедентную возможность снова использовать код. В Mac OS 9, например, все комплекты разработчика программного обеспечения (SDKs) были независимы друг от друга, копировав функциональность между ними. В OS X Набор I/O поставлен как часть основных инструментов разработчика, и код совместно используется среди его различных частей.
В отличие от традиционных моделей I/O, модель повторно используемого кода, предоставленная Набором I/O, может уменьшить Вашу техническую разработку существенно. В портировании драйверов от Mac OS 9, например, дубликаты OS X были до 75% меньшими.
В целом вся поддержка оборудования предоставлена непосредственно объектами Набора I/O. Одно исключение к этому правилу является устройствами отображения, такими как принтеры, сканеры и цифровые фотоаппараты (несмотря на то, что они действительно некоторые используют функциональность Набора I/O). В частности, несмотря на то, что связь с этими устройствами обрабатывается Набором I/O (например, под семьями FireWire или USB), поддержка определенных характеристик устройства обрабатывается кодом пространства пользователя (см. Для получения дополнительной информации для дальнейшего обсуждения). Если необходимо поддерживать устройства отображения, необходимо использовать надлежащий комплект разработчика программного обеспечения (SDK) обработки изображений.
Набор I/O пытается представлять в программном обеспечении, та же иерархия, существующая в аппаратных средствах. Некоторые вещи являются трудными к краткому обзору, как бы то ни было. Когда аппаратную иерархию трудно представлять (например, если разделяющие на уровни нарушения происходят), тогда абстракции Набора I/O обеспечивают меньше справки для записи драйверов.
Кроме того, все драйверы существуют для управления аппаратными средствами; все аппаратные средства отличаются. Даже с допускающей повторное использование моделью, предоставленной Набором I/O, все еще необходимо знать о любых аппаратных причудах, которые могут повлиять на высокоуровневое представление устройства. Код для поддержки тех причуд все еще должен быть уникальным с драйвера на драйвер.
Несмотря на то, что большинство разработчиков должно быть в состоянии в полной мере воспользоваться семействами устройства Набора I/O (см. семьи), иногда будут некоторые, кто не может. Даже те разработчики должны быть в состоянии использовать части Набора I/O, как бы то ни было. В любом случае исходный код всегда доступен. Если необходимо сделать так, можно заменить функциональность и изменить классы сами.
В разработке Набора I/O одна цель состояла в том, чтобы сделать жизни разработчиков проще. К сожалению, не возможно сделать жизни всех разработчиков унифицированно простыми. Поэтому вторая цель проекта Набора I/O состоит в том, чтобы удовлетворить потребности большинства разработчиков, не мешая меньшинству, кто должен понизить доступ уровня к аппаратным средствам.
Архитектура Набора I/O
Набор I/O обеспечивает модель оборудования системы в объектно-ориентированной платформе. Каждый тип службы или устройства представлен классом C++; каждая дискретная служба или устройство представлены экземпляром (объект) того класса.
Существует три главных концептуальных элемента архитектуры Набора I/O:
Семьи
Семья определяет набор высокоуровневых абстракций, характерных для всех устройств определенной категории, принимающей форму кода C и классов C++. Семьи могут включать заголовки, библиотеки, пример кода, тестовые ремни безопасности и документацию. Они обеспечивают API, универсальный код поддержки и по крайней мере один драйвер в качестве примера (в документации).
Семьи предоставляют услуги для многих различных категорий устройств. Например, существуют семейства протокола (такие как SCSI, USB и FireWire), семейства систем хранения (диск), сетевые семьи и семьи для описания устройств интерфейса пользователя (мышь и клавиатура). Когда устройства имеют функции вместе, программное обеспечение, поддерживающее те функции, наиболее вероятно найдено в семье.
Общие абстракции определены и реализованы семьей, позволив все драйверы в семье совместно использовать подобные функции легко. Например, все контроллеры SCSI имеют определенные вещи, которые они должны сделать, такие как сканирование шины SCSI. Семья SCSI определяет и реализует функциональность, которая характерна для контроллеров SCSI. Поскольку эта функциональность была включена в семью SCSI, Вы не должны включать код сканирования (например), в Ваш новый драйвер контроллера SCSI.
Вместо этого можно сконцентрироваться на специфичных для устройства подробных данных, делающих драйвер отличающимся от других драйверов SCSI. Использование семей означает, что существует меньше кода для Вас для записи.
Семьи являются динамично загружаемыми; они загружаются, при необходимости и разгружено, когда больше не необходимый. Несмотря на то, что некоторые общие семьи могут быть предварительно загружены при системном запуске, все семьи должны считаться динамично загружаемыми (и, поэтому, потенциально разгружаться). Посмотрите Пример Соединения для иллюстрации.
Драйверы
Драйвер является объектом Набора I/O, управляющим определенным устройством или шиной, представляя более абстрактное представление того устройства к другим частям системы. Когда драйвер загружается, его требуемые семьи также загружаются для обеспечения необходимой, общей функциональности. Запрос для загрузки драйвера заставляет все свои зависимые требования (и их требования) быть загруженными сначала. После того, как все требования удовлетворяются, требуемый драйвер загружается также. Посмотрите Пример Соединения для иллюстрации.
Обратите внимание на то, что семьи загружаются по требованию драйвера, не наоборот. Иногда, семья может уже быть загружена, когда драйвер требует его; однако, Вы никогда не должны принимать это. Чтобы гарантировать, что все требования удовлетворяются, каждый драйвер устройства должен перечислить все свои требования в его списке свойств.
Большинство драйверов находится в отношении клиентского провайдера, в чем драйвер должен знать и о семье, от которой он наследовался и семья, с которой он соединяется. Драйвер контроллера SCSI, например, должен быть в состоянии связаться и с семьей SCSI и с семьей PCI (как клиент PCI и провайдер SCSI). Драйвер диска SCSI связывается и с SCSI и с семействами систем хранения.
Куски
Кусок является объектом Набора I/O, представляющим точку соединения для драйвера. Это представляет управляемый объект, такой как диск или шина.
Кусок загружается как часть семьи, инстанцирующей его. Каждый кусок обеспечивает доступ к устройству или службе, что это представляет и предоставляет услуги, такие как соответствие, арбитраж и управление питанием.
Понятие кусков может более легко визуализироваться путем воображения телевизора. Существует провод, присоединенный к Вашей стене, обеспечивающей телевизионную услугу от где-нибудь. Для всех практических целей это постоянно связано с тем провайдером, класс инстанцирования (кабельная компания, установившая строку). Это может быть присоединено к TV для обеспечения услуги (кабельное телевидение). Тот провод является куском.
Каждый кусок обеспечивает мост между двумя драйверами (и, расширением, между двумя семьями). Наиболее распространено, что драйвер публикует один кусок для каждого отдельного устройства или службы, которой это управляет. (В этом примере вообразите один провод для каждого дома обслуживаемым кабельной компанией.)
Это также возможно для драйвера, управляющего только единым устройством или службой для действия как ее собственный кусок. (Вообразите антенну в конце своего TV, имеющего встроенный провод.) Посмотрите Пример Соединения для иллюстрации отношения между кусками и драйверами.
Пример соединения
Рисунок 12-1 иллюстрирует архитектуру Набора I/O, с помощью нескольких драйверов в качестве примера и их соответствующих кусков. Обратите внимание на то, что много различных комбинаций драйвера возможны; эта схема показывает только одну возможность.
В этом случае штабель SCSI показан, с контроллером PCI, диском и сканером SCSI. Диском SCSI управляет резидентный ядром драйвер. Сканером SCSI управляет драйвер, который является частью пользовательского приложения.
Этот пример иллюстрирует, как драйвер диска SCSI (Семейство систем хранения) подключен к шине PCI. Соединение сделано на нескольких шагах.
Драйвер шины PCI обнаруживает устройство PCI и объявляет о его присутствии путем создания куска (
IOPCIDevice
). Класс куска определяется семьей PCI.Драйвер шины идентифицирует (соответствует) драйвер правильного устройства и запрашивает, чтобы был загружен драйвер. В конце этого процесса соответствия драйвер контроллера SCSI был найден и загружен. Загрузка драйвера контроллера заставляет все требуемые семьи быть загруженными также. В этом случае семья SCSI загружается; семья PCI (также требуемый) уже присутствует. Драйверу контроллера SCSI дают ссылку на
IOPCIDevice
кусок.Драйвер контроллера SCSI сканирует шину SCSI для устройств. После нахождения устройства это объявляет о присутствии устройства путем создания куска (
IOSCSIDevice
). Класс этого куска определяется семьей SCSI.Драйвер контроллера идентифицирует (соответствует) драйвер правильного устройства и запрашивает, чтобы был загружен драйвер. В конце этого процесса соответствия дисковый драйвер был найден и загружен. Загрузка дискового драйвера заставляет все требуемые семьи быть загруженными также. В этом случае Семейство систем хранения загружается; семья SCSI (также требуемый) уже присутствует. Дисковому драйверу дают ссылку на
IOSCSIDevice
кусок.
Для получения дополнительной информации
Для получения дополнительной информации о Наборе I/O необходимо считать документ Основные принципы IOKit, доступные от веб-сайта документации разработчика Apple, http://developer .apple.com/documentation. Это обеспечивает хороший общий обзор Набора I/O.
В дополнение к Основным принципам IOKit веб-сайт содержит много документов HOWTO и специфичных для темы документов, описывающих проблемы, определенные для определенных технологических областей, таких как FireWire и USB.