Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие 3000377.doc
Скачиваний:
29
Добавлен:
30.04.2022
Размер:
2.52 Mб
Скачать

Очереди запросов под управлением драйвера

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

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

Драйвер может создать собственную очередь запросов с помощью функции режима ядра KeInitializeDeviceQueue, определенной следующим образом:

VOID KeInitializeDeviceQueue( IN PKDEVICE_QUEUE DeviceQueue );

Здесь параметр DeviceQueue указывает на экземпляр структуры KDEVICE_QUEUE, предварительно размещенный драйвером в системной области памяти. Таким образом, драйвер может инициализировать заголовок собственной очереди запросов и, при необходимости, создать любое количество таких очередей.

Драйвер может добавлять запросы в очередь при помощи функций KeInsertDeviceQueue и KeInsertByKeyDeviceQueue, и извлекать буферизированные запросы из очереди с помощью функций KeRemoveDeviceQueue и KeRemoveByKeyDeviceQueue.

Кроме того, драйвер может создать собственную низкоуровневую очередь, используя поле Overlay.ListEntry структуры IRP. Эта очередь не имеет какой-либо системой поддержки и может реализовывать любую стратегию буферизации и сортировки запросов, по усмотрению разработчика драйвера.

3.6. Диспетчер Plug-And-Play, установка и запуск драйверов

В решении задач сопоставления драйверов с физическими устройствами, загрузки и запуска драйверов важную роль играет диспетчер PnP.

Технология PnP предоставляет следующие возможности:

  • автоматическое распознание устройств на шинах, включая перечисление устройств на этапе загрузки операционной системы и изменение аппаратной конфигурации во время работы;

  • автоматическое распределение аппаратных ресурсов, таких как прерывания, порты ввода-вывода или адреса прямого доступа к памяти между устройствами на шинах компьютера;

  • автоматическая загрузка требуемых драйверов, если эти драйверы установлены в системе, или автоматический запрос на инсталляцию отсутствующих драйверов.

Работа диспетчера PnP основана на промышленных стандартах обнаружения и идентификации устройств, подключенных к шинам компьютеров. Устройства, поддерживающие стандарт PnP, должны отвечать на стандартизированные запросы драйверов шин, сообщая идентификационную информацию о себе. Диспетчер PnP выполняет перечисление всех устройств на этапе загрузки операционной системы, запрашивая у драйверов шин описание обнаруженных устройств, загружает требуемые драйверы и через поле DriverExtension->AddDevice структуры DRIVER_OBJECT вызывает процедуру добавления устройства, определенную в составе PnP драйвера. Процедура добавления устройства создает объект устройство (экземпляр структуры DEVICE_OBJECT) посредством вызова функции IoCreateDevice и встраивает это устройство в стек обработки запросов ввода-вывода посредством вызова функции IoAttachDeviceToDeviceStack. При необходимости, здесь же может быть создана символическая ссылка на устройство для доступа к нему из пользовательского режима через системный вызов DeviceIoControl.

Но после создания устройства драйвер еще не может приступить к управлению им, поскольку ему еще не известны ресурсы (порты ввода-вывода, отображение памяти, каналы DMA), отведенные для взаимодействия с устройством. Добавленное устройство пока остается неактивным и драйвер не обслуживает его.

После того, как диспетчер PnP перечислит все устройства, он запускает процедуру арбитража ресурсов, чтобы бесконфликтно распределить аппаратные ресурсы между всеми обнаруженными устройствами. Закончив арбитраж ресурсов, диспетчер PnP передает загруженным драйверам команду IRP_MN_START_DEVICE блок стека IRP которой в поле Parameters.StartDevice.AllocatedResourcesTranslated структуры IO_STACK_LOCATION содержит ссылку на перечень ресурсов, назначенных устройству.

Указанное поле блока стека IRP поле хранит указатель на экземпляр структуры CM_RESOURCE_LIST, определенной следующим образом:

struct CM_RESOURCE_LIST { ULONG Count; // число элем. в следующем массиве CM_FULL_RESOURCE_DESCRIPTOR List[1]; };

В свою очередь, каждый элемент массива List определяет один вид распределенного ресурса (диапазон адресов памяти, порты ввода-вывода и т.п.). Он содержит экземпляр структуры CM_FULL_RESOURCE_DESCRIPTOR, определенной следующим образом:

struct CM_FULL_RESOURCE_DESCRIPTOR { INTERFACE_TYPE InterfaceType; ULONG BusNumber; CM_PARTIAL_RESOURCE_LIST PartialResourceList; };

Поле InterfaceType определяет тип интерфейса, по которому выполняется доступ к ресурсу. Например, Isa, PCIBus, PCMCIABus. Поле BusNumber определяет номер шины в условной нумерации диспетчера PnP. Оба описанных поля не используются WDM драйверами устройств, которые получают всю необходимую информацию о ресурсах через поле PartialResourceList, представляющее собой экземпляр структуры CM_PARTIAL_RESOURCE_LIST, определенной следующим образом:

struct CM_PARTIAL_RESOURCE_LIST { USHORT Version; USHORT Revision; ULONG Count; // число элементов в сл. массиве CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]; };

Поля Version и Revision определяют версию структуры CM_PARTIAL_RESOURCE_LIST. Поле PartialDescriptors представляет собой массив экземпляров структуры CM_PARTIAL_RESOURCE_DESCRIPTOR, каждый из которых содержит описание конкретного распределенного ресурса. Отметим некоторые поля этой структуры:

  • UCHAR Type – тип ресурса, например CmResourceTypePort – порт ввода-вывода, CmResourceTypeInterrupt – прерывание, CmResourceTypeDma – канал прямого доступа к памяти;

  • UCHAR ShareDisposition – определяет, может ли данный ресурс разделяться с другими устройствами: CmResourceShareDeviceExclusive – ресурс не может разделяться, CmResourceShareShared – ресурс, например прерывание, может разделяться с др. устройствами;

  • union { … struct { PHYSICAL_ADDRESS Start; ULONG Length; } Port; // диапазон портов в.-в. struct { ULONG Level; ULONG Vector; ULONG Afinity; } Interrupt; // прерывание struct { PHYSICAL_ADDRESS Start; ULONG Length; } Memeory; // диапазон адресов памяти … } u – описание ресурса в зависимости от его типа.

Передача драйверу информации о ресурсах, распределенных контролируемому устройству, поясняется рис. .21.

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

Если в ходе работы системы диспетчеру PnP понадобится перераспределить ресурсы между устройствами, например при подключении нового устройства, диспетчер сначала должен будет остановить работу устройства в текущей конфигурации, а затем передать драйверу команду IRP_MN_START_DEVICE с новыми параметрами.

Диспетчер PnP определяет драйверы, необходимые для работы обнаруженных устройств, основываясь на информации из ветви реестра HKLM\System\CurrentControlSet\Enum, которая содержит перечень всех устройств, которые когда-либо были подключены к компьютеру.

Рис.21. Передача драйверу информации о распределенных ресурсах

В разделе реестра Enum для каждого устройства содержится параметр Service, в котором хранится ссылка на раздел реестра HKLM\System\CurrentControlSet\Services. В этом разделе, в свою очередь, для каждого сервиса содержится параметр ImagePath, в котором хранится имя файла с образом драйвера.

Например:

HKLM\System\CurrentControlSet\Enum\USB\ Vid_0930&Pid_6533\09517B405041BBAB\Service = USBSTOR HKLM\System\CurrentControlSet\Services\USBSTOR\ ImagePath =system32\DRIVERS\USBSTOR.SYS

Если для устройства установлен фильтр верхнего или нижнего уровня, то сведения о драйверах фильтров также хранятся реестре. Если для работы устройства требуется фильтр то в записи об этом устройстве в ветви HKLM\System\CurrentControlSet\Enum указывается текстовый параметр UpperFilters и/или LowerFilters, в котором записана ссылка на соответствующий раздел в ветви HKLM\System\CurrentControlSet\Services. При необходимости использовать несколько фильтров, их имена перечисляются в переменных UpperFilters или LowerFilters в формате REG_MULTI_SZ в виде последовательности текстовых строк, разделенных нулями. При этом список заканчивается двумя нулевыми символами.

Драйверы фильтры могут устанавливаться не только для отдельных устройств, но и для всего класса устройств. Для каждого устройства, перечисленного в ветви реестра HKLM\System\CurrentControlSet\Enum, представлен параметр ClassGUID, хранящий уникальный идентификатор класса устройства, который является ключом в ветви реестра HKLM\System\CurrentControlSet\Control\Class. При необходимости использовать фильтр для всех устройств данного класса в параметры класса необходимо включить переменные UpperFilters или LowerFilters, хранящие имена соответствующих разделов в ветви реестра HKLM\System\CurrentControlSet\Services.

При подключении к компьютеру PnP устройства драйвер шины запрашивает его идентификатор, после чего диспетчер PnP проводит поиск устройства в ветви реестра HKLM\System\CurrentControlSet\Enum. Если там найден идентификатор подключенного устройства, система загружает заранее известный драйвер и устройство начинает работать. Если обнаруживается подключение ранее неизвестного устройства, система генерирует запрос на установку драйвера.

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

В системе Windows возможно три способа установки драйвера:

  • автоматическая установка на основе INF-файла;

  • установка программой инсталляции, использующей системный интерфейс SetupAPI;

  • прямая модификация реестра и копирование данных вручную или с использованием вспомогательных программ.

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

Установка драйвера с использованием INF-файла наиболее проста с точки зрения разработчика драйвера (необходимо подготовить и поставлять с драйвером простой текстовый файл), но требует от пользователя хотя бы минимальных знаний в области администрирования системы.

Установка драйверов с помощью программы инсталляции наиболее удобна для конечного пользователя и не требует от него специальных знаний или навыков. Установка выполняется запуском программы инсталляции, которая делает все необходимые копирования файлов и записи в реестре.

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