Узлы устройств и стеки устройств

В Windows устройства представлены узлами устройств в дереве устройств Plug and Play (PnP). Как правило, при отправке запроса ввода-вывода на устройство несколько драйверов помогают обработать запрос. Каждый из этих драйверов связан с объектом устройства, а объекты устройства расположены в стеке. Последовательность объектов устройства вместе со связанными с ними драйверами называется стеком устройств. Каждый узел устройства имеет собственный стек устройств.

Узлы устройств и дерево устройств Plug and Play

Windows упорядочивает устройства в древовидную структуру, называемую деревом устройств Plug and Play или просто деревом устройств. Как правило, узел в дереве устройств представляет либо устройство, либо отдельную функцию на составном устройстве. Однако некоторые узлы представляют программные компоненты, которые не имеют связи с физическими устройствами.

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

схема дерева устройств, показывающая узлы устройств.

Дерево устройств иллюстрирует отношения "родители-потомки", присущие среде PnP. Несколько узлов в дереве устройств представляют автобусы, к которым подключены дочерние устройства. Например, узел шины PCI представляет физическую шину PCI на системной плате. Во время запуска диспетчер PnP просит драйвера шины PCI перечислить устройства, подключенные к шине PCI. Эти устройства представлены дочерними узлами узла шины PCI. На предыдущей схеме узел шины PCI имеет дочерние узлы для нескольких устройств, подключенных к шине PCI, включая usb-контроллеры узлов, звуковой контроллер и порт PCI Express.

Некоторые устройства, подключенные к шине PCI, сами являются автобусами. Менеджер PnP просит каждый из этих автобусов перечислить подключенные к нему устройства. На предыдущей схеме видно, что звуковой контроллер — это шина, к которому подключено звуковое устройство. Мы видим, что порт PCI Express — это шина, к которому подключен адаптер дисплея, а адаптер дисплея — это шина, к ней подключен один монитор.

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

Объекты устройств и стеки устройств

Объект устройства — это экземпляр структуры DEVICE_OBJECT. Каждый узел устройства в дереве устройств PnP имеет упорядоченный список объектов устройств, и каждый из этих объектов устройства связан с драйвером. Упорядоченный список объектов устройств вместе со связанными с ними драйверами называется стеком устройств для узла устройства.

Стек устройств можно представить несколькими способами. В самом формальном смысле стек устройств — это упорядоченный список пар (объект устройства, драйвер). Однако в некоторых контекстах может быть полезно рассматривать стек устройств как упорядоченный список объектов устройства. В других контекстах может быть полезно рассматривать стек устройств как упорядоченный список драйверов.

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

На следующей схеме узел устройства Proseware Gizmo содержит стек устройств, содержащий три пары (объект устройства, драйвер). Верхний объект устройства связан с драйвером AfterThought.sys, средний объект устройства — с Proseware.sys драйвера, а нижний объект устройства — с Pci.sys драйвера. Узел шины PCI в центре схемы содержит стек устройств, содержащий две пары (объект устройства, драйвер) — объект устройства, связанный с Pci.sys, и объект устройства, связанный с Acpi.sys.

схема, показывающая объекты устройств, упорядоченные в стеках устройств в узлах устройств proseware gizmo и pci.

Как создается стек устройств?

Во время запуска диспетчер PnP просит водителя для каждой шины перечислить дочерние устройства, подключенные к шине. Например, диспетчер PnP просит водителя шины PCI (Pci.sys) перечислить устройства, подключенные к шине PCI. В ответ на этот запрос Pci.sys создает объект устройства для каждого устройства, подключенного к шине PCI. Каждый из этих объектов устройства называется физическим объектом устройства (PDO). Вскоре после того, как Pci.sys создаст набор PDO, дерево устройств будет выглядеть так, как показано на следующей схеме.

схема узлов Pci и объектов физических устройств для дочерних устройств.

Диспетчер PnP связывает узел устройства с каждым вновь созданным PDO и ищет в реестре, чтобы определить, какие драйверы должны входить в стек устройств для узла. Стек устройств должен иметь один (и только один) драйвер функции и при необходимости может иметь один или несколько драйверов фильтров. Драйвер функции является драйвером main для стека устройств и отвечает за обработку запросов на чтение, запись и управление устройством. Драйверы фильтров играют вспомогательные роли при обработке запросов на чтение, запись и управление устройствами. При загрузке каждой функции и драйвера фильтра он создает объект устройства и присоединяется к стеку устройств. Объект устройства, созданный драйвером функции, называется объектом функционального устройства (FDO), а объект устройства, созданный драйвером фильтра, называется объектом устройства фильтра (Filter DO). Теперь дерево устройств выглядит примерно так, как на этой схеме.

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

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

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

Примечание При установке драйверов для устройства установщик использует сведения в файле сведений (INF), чтобы определить, какой драйвер является драйвером функции, а какие драйверы являются фильтрами. Как правило, INF-файл предоставляется корпорацией Майкрософт или поставщиком оборудования. После установки драйверов для устройства диспетчер PnP может определить функции и драйверы фильтров для устройства, зайдя в реестр.

Водители автобусов

На предыдущей схеме видно, что драйвер Pci.sys играет две роли. Во-первых, Pci.sys связан с FDO в узле устройства шины PCI. Фактически он создал FDO в узле устройства шины PCI. Таким образом, Pci.sys является драйвером функции для шины PCI. Во-вторых, Pci.sys связан с PDO в каждом дочернем узле шины PCI. Напомним, что она создала PDO для дочерних устройств. Драйвер, который создает PDO для узла устройства, называется драйвером шины для узла.

Если точкой отсчета является шина PCI, то Pci.sys — драйвер функции. Но если вашей точкой отсчета является устройство Proseware Gizmo, то Pci.sys является водителем автобуса. Эта двойная роль является типичной в дереве устройств PnP. Водитель, который служит в качестве водителя-функции для автобуса, также выступает в качестве водителя автобуса для дочернего устройства автобуса.

Стеки устройств в пользовательском режиме

До сих пор мы обсуждали стеки устройств в режиме ядра. То есть драйверы в стеках работают в режиме ядра, а объекты устройства сопоставляются с системным пространством, которое является адресным пространством, доступным только для кода, выполняющегося в режиме ядра. Сведения о различиях между режимами ядра и пользовательскими режимами см. в разделе Пользовательский режим и режим ядра.

В некоторых случаях устройство имеет стек устройств в пользовательском режиме в дополнение к стеку устройств в режиме ядра. Драйверы пользовательского режима часто основаны на User-Mode Driver Framework (UMDF), которая является одной из моделей драйверов, предоставляемых платформами windows Driver Framework (WDF). В UMDF драйверами являются библиотеки DLL в пользовательском режиме, а объекты устройств — com-объекты, реализующие интерфейс IWDFDevice. Объект устройства в стеке устройств UMDF называется объектом устройства WDF (WDF DO).

На следующей схеме показан узел устройства, стек устройств в режиме ядра и стек устройств в пользовательском режиме для устройства USB-FX-2. Драйверы как в стеке пользовательского, так и в режиме ядра участвуют в запросах ввода-вывода, которые направляются на устройство USB-FX-2.

схема, показывающая стеки устройств в пользовательском режиме и режиме ядра.

Основные понятия для всех разработчиков драйверов

Стеки драйверов