Программирование драйверов Windows

       

Автоматическое распознавание и конфигурирование


За каждым аппаратным устройством, подключенным к компьютеру, закрепляются системные ресурсы, которые могут включать:

  • диапазон адресов ввода/вывода (портов вода/вывода);
  • диапазон отведенных адресов памяти;
  • номер прерывания IRQ;
  • DMA канал.
  • Поскольку разные устройства были изготовлены в разное время разными поставщиками, то конфликты ресурсов совершенно неизбежны. Первые персональные компьютеры требовали немалой сообразительности от пользователя при конфигурировании подключаемых устройств, правильного, а подчас — единственно верного, выставления перемычек или DIP переключателей, определяющих уникальную настройку ресурсов для данной системы. Инсталляция нового устройства требовала знания, какие ресурсы уже выделены существующим устройствам. Ошибки в таком ручном конфигурировании были частыми, а результатом были либо невозможность загрузить систему, либо непредсказуемые зависания системы и неработающие устройства.

    Для преодоления этих проблем были введены новые принципы построения шинных архитектур, которые бы поддерживали автоматическое распознавание и конфигурирования устройств. Автоматическое распознавание должно происходить в момент загрузки/перезагрузки системы или непосредственно в момент подключения устройства к компьютеру ("горячее" подключение). Возможности операционной системы, соответственно, должны быть таковы, чтобы соответствующее сопроводительное программное обеспечение вступало в работу без общей перезагрузки системы.

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


    Спецификация PCI обязывает каждую отдельную функцию (функциональную единицу устройства, а значит, и шины) иметь свою собственную область для хранения конфигурационных данных, размер которой равен 256 байт. Эта область известна как конфигурационное пространство функциональных единиц PCI (PCI function's configuration space).

    Первые 64 байта такого конфигурационного пространства (называемого заголовком) имеют предопределенную структуру (таблица 2.4), в то время как остальные 192 байта могут быть использованы по усмотрению разработчика данной PCI платы. Системное программное обеспечение может использовать этот заголовок для идентификации функциональной единицы PCI и выделения ей ресурсов. Заголовок включает:

  • Информацию о поставщике (Vendor ID), тип устройства (Device ID) и версию устройства (Revision ID).
  • Два стандартных регистра состояния команд для того, чтобы имелась возможность работы с ошибками в устройстве (Status Register и Command Register).


  • Список ресурсов, в котором описываются требования к памяти и пространству ввода/вывода.
  • Регистр вывода прерывания (Int Pin) и регистр линии прерывания (Int Line), описанные выше.
  • Указатель на расширение ПЗУ (Expansion ROM Base Address), специфичное для данного устройства.
  • Регистр Class Code внутренне разбит на три поля (Class Code, старший байт, Sub-Class Code и ProgIF, младший байт) и содержит информацию для использования классовыми системными драйверами (предназначенными для обслуживания целого класса родственных устройств, например, сетевых контроллеров, устройств мультимедиа, docking-станций, шинных мостов, кодирующих/декодирующих контроллеров, интеллектуальных контроллеров ввода/вывода). Например, значение Class Code, равное 0C (hex), в спецификации PCI 2.2 определяет контроллеры последовательных шин. Тогда значение Sub-Class Code, равное 00, определяет IEEE 1394, 01 &#8212 ACCESS.bus, 02 &#8212 SSA (Serial Storage Architecture), 03 &#8212 USB, 04 &#8212 Fibre Channel, 05 &#8212 SMBus (System Management Bus).


    Спецификация шины 1394 была разработана с непосредственной поддержкой спецификации PnP. Каждое устройство при подключении к шине сигнализирует о своем существовании при выполнении шинной операции 'reset', что в сильной степени напоминает способ обращения с шиной USB и ее устройствами. Хост-компьютер (или другие узлы) выполняют операцию "перечисления" конфигурационных ПЗУ для того, чтобы обнаружить данное устройство и обеспечить запуск (а при необходимости &#8212 и инсталляцию) соответствующего драйвера.




    Спецификация USB была разработана с непосредственной поддержкой спецификации PnP (иногда кажется, что &#8212 с откровенной ориентацией на WDM модель драйверов Windows). Каждое USB устройство при подключении к шине USB сигнализирует о своем существовании и сообщает идентификатор производителя (vendor ID) и идентификатор устройства (device ID). Эти идентификаторы являются определяющей информацией в выборе загружаемого драйвера &#8212 соответствующая информация должна присутствовать в Системном Реестре (если ничего подходящего там не обнаруживается, то инициируется процесс установки нового драйвера).




    Стандарт шины PC Card удовлетворяет спецификации PnP полностью, хотя еще продолжается внесение изменений, касающихся "горячего подключения" устройств и автоматического конфигурирования.

    Программное обеспечение для стандартов PC Card или CardBus разделяется на два крупных фрагмента: Сервисы Сокетов, Socket Services (в данном случае, socket &#8212 гнездо, разъем), и Службы Карт (Card Services). Первый представляет программное обеспечение уровня BIOS, и оно управляет в системе одним или более разъемов. Это программное обеспечение отвечает за обнаружение и объявление факта подключения нового устройства. Вторая часть (Card Service) управляет аппаратными ресурсами данной карты.




    Для подкласса USB значение ProgIF, равное 00, описывает USB контроллер, соответствующий спецификации Universal host Controller. Значению 10 (hex) соответствует контроллер спецификации Open Host Controller, а значение FE (hex) описывает USB устройство (не являющееся хост-контроллером).

    Байты конфигурационного пространства
    3 2 1 0  
    Device ID Vendor ID 00
    Status Register Command Register 01
    Class Code Revision ID 02
    BIST Header Type Lat Timer CL Size 03
    Base Address 0 04
    Base Address 1 05
    Base Address 2 06
    Base Address 3 07
    Base Address 4 08
    Base Address 6 09
    Card Bus CIS Pointer 0A
    Subsystem ID Subsystem Vendor ID 0B
    Expansion ROM Base Address 0C
    Зарезервировано Cap.Pointer 0D
    Зарезервировано 0E
    Max_Lat Min_Gnt int Pin int Line 0F
    Таблица 5.4.

    Заголовок конфигурационного пространства одной функции устройства PCI
    Регистр BIST (Built-In-Self-Test) отражает способность устройства к проведению операции самотестирования. Единица в старшем (седьмом) бите этого регистра означает, что данная функция устройства может выполнять операцию самотестирования. Шестой бит, установленный в 1, означает проведение тестирования, причем на эту операцию функции устройства дается не более 2-х секунд. В младших четырех битах содержится код ошибки либо 0, при удачном завершении.

    Регистры Base Address Register 5..0 содержат адреса портов ввода/вывода (или диапазонов отведенной памяти) для доступа к внутренней памяти данной PCI функции.

    Отображать все 256 адресов конфигурационного пространства в памяти или пространстве ввода/вывода достаточно расточительно, поэтому операционная система дает возможность доступа к конфигурационному пространству путем обращения к следующим двум регистрам (адреса которых устанавливаются операционной системой):

  • Конфигурационный адресный регистр. Этот регистр определяет номер шины (bus number), устройство, функцию и адрес доступа к данным в конфигурационном пространстве.




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


  • Операционная система предоставляет HAL функции для доступа к конфигурационным данным. Для этого предлагается использовать функции HalGetBusData, HalSetBusData и HalAssignSlotResources. Правда, в WDM модели они считаются устаревшими (даже их описание в DDK отсутствует) — рекомендовано работать через запросы к нижнему драйверу стека.

    Для идентификации драйвера, загружаемого операционной системой для обслуживания данного устройства, спецификация PCI рекомендует разработчикам ОС использовать информацию из конфигурационных регистров Vendor ID, Device ID, Revision ID, Class Code, Subsystem Vendor ID, Subsystem ID (последние два стали обязательными только в спецификации версии 2.2).


    Содержание раздела