设备节点和设备堆栈

MSDN原文:https://msdn.microsoft.com/zh-cn/library/windows/hardware/ff554721(v=vs.85).aspx

在 Windows 中,设备由即插即用 (PnP) 设备树中的设备节点来表示。通常,向设备发送 I/O 请求时,一些驱动程序会帮助处理该请求。这些驱动程序中的每一个都与一个设备对象相关联,这些设备对象在堆栈中进行排列。设备对象的顺序与它们的关联驱动程序一起被称为设备堆栈。每个设备节点都有自己的设备堆栈。

设备节点和即插即用设备树

Windows 在称为“即插即用设备树”或简称为“设备树”的树结构中整理设备。 通常,设备树中的节点表示复合设备上的某个设备或单个函数。 但是,某些节点表示与物理设备无关联的软件组件。

设备树中的节点称为“设备节点”。设备树的根节点称为“根设备节点”。常规情况下,根设备节点绘制在设备树的底部,如下图所示。

设备树说明了 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 关联。

如何构建设备堆栈?

在启动过程中,PnP 管理器请求每个总线的驱动程序枚举连接到该总线的子设备。例如,PnP 管理器请求 PCI 总线驱动程序 (Pci.sys) 枚举连接到该 PCI 总线的设备。为了响应此请求,Pci.sys 会为连接到 PCI 总线的每个设备创建一个设备对象。这些设备对象中的每一个都被称为“物理设备对象”(PDO)。在 Pci.sys 创建该组 PDO 不久之后,设备树类似于下图中的一个设备树。

PnP 管理器将设备节点与每个新创建的 PDO 关联,并查询注册表以确定哪些驱动程序需要成为该节点设备堆栈的一部分。设备堆栈必须具有一个(且只有一个)“函数驱动程序”,并且可以选择具有一个或多个“筛选器驱动程序”。函数驱动程序为设备堆栈的主要驱动程序且负责处理读、写以及设备控制请求。筛选器驱动程序在处理读、写以及设备控制请求中扮演辅助角色。加载每个函数驱动程序和筛选器驱动程序时,它都会创建一个设备对象并将其自身附加到设备堆栈。由函数驱动程序创建的设备对象称为“函数设备对象”(FDO),由筛选器驱动程序创建的设备对象称为“筛选器设备对象”(筛选器 DO)。现在设备树类似于此图。

在该图中,注意在一个节点中,筛选器驱动程序位于函数驱动程序之上,而在另一节点中,筛选器驱动程序位于函数驱动程序之下。在设备堆栈中位于函数驱动程序之上的筛选器驱动程序称为“上筛选器驱动程序”。位于函数驱动程序之下的筛选器驱动程序称为“下筛选器驱动程序”。

PDO 始终为设备堆栈中的底部设备对象。这缘于设备堆栈的构造方式。PDO 最先创建,并且当其他设备对象附加到堆栈中时,这些对象会附加到现有堆栈的顶部。

注意

安装设备驱动程序后,安装程序使用信息 (INF) 文件中的信息来确定哪个驱动程序为函数驱动程序,哪些驱动程序为筛选器。通常,INF 文件由 Microsoft 或硬件供应商提供。安装设备驱动程序后,PnP 管理器可以通过查找注册表来确定设备的函数驱动程序和筛选器驱动程序。

总线驱动程序

在上图中,你可以看到驱动程序 Pci.sys 扮演两个角色。第一,Pci.sys 与 PCI 总线设备节点中的 FDO 关联。事实上,Pci.sys 已在 PCI 总线设备节点中创建 FDO。因此,Pci.sys 为 PCI 总线的函数驱动程序。第二,Pci.sys 与 PCI 总线节点的每个子节点中的 PDO 关联。谨记 Pci.sys 已为子设备创建 PDO。为设备节点创建 PDO 的驱动程序称为该节点的“总线驱动程序”。

如果你的参考点为 PCI 总线,则 Pci.sys 为函数驱动程序。但如果你的参考点为 Proseware Gizmo 设备,则 Pci.sys 为总线驱动程序。此双重角色为 PnP 设备树中的典型。作为总线的函数驱动程序的驱动程序也是总线子设备的总线驱动程序。

用户模式设备堆栈

到目前为止,我们已介绍了内核模式设备堆栈。即,堆栈中的驱动程序在内核模式下运行,设备对象映射到系统空间,该空间是唯一一个以内核模式运行的代码能够使用的地址空间。有关内核模式与用户模式之间差异的信息,请参阅用户模式和内核模式

在某些情形下,设备不仅具有内核模式设备堆栈,同时还有用户模式设备堆栈。用户模式驱动程序通常基于用户模式驱动程序框架 (UMDF),它是 Windows 驱动程序框架 (WDF) 提供的驱动程序模型之一。在 UMDF 中,驱动程序为用户模式 DLL,设备对象为实现 IWDFDevice 接口的 COM 对象。UMDF 设备堆栈中的设备对象称为“WDF 设备对象”(WDF DO)。

下图显示了设备节点、内核模式设备堆栈以及 USB-FX-2 设备的用户模式设备堆栈。用户模式和内核模式堆栈中的驱动程序参与在 USB-FX-2 设备上定向的 I/O 请求。

时间: 2024-10-11 07:49:17

设备节点和设备堆栈的相关文章

【Linux驱动】自动创建设备节点

开始学习驱动的时候,是将驱动程序编译成模块然后用mknod命令手动建立设备节点以提供给应用程序调用.这对于刚开始调试驱动程序的时候常用的一种方法.但是,当有种需要必须在系统启动的时候就将驱动程序就绪,来供应用层程序调用.这时就不能再手动的建立设备节点了,而必须自动的创建设备节点(不需要人为的操作). ★注册类 注册类的目的是为了使mdev可以在/dev/目录下建立设备节点. 首先要定义一个类,利用struct class结构体.这个结构体定义在头文件include/linux/device.h中

设备与驱动的关系以及设备号、设备文件

Linux设备分类Linux下的设备通常分为三类,字符设备,块设备和网络设备. 字符设备 一个字符设备是一种字节流设备,对设备的存取只能按顺序按字节的存取而不能随机访问,字符设备没有请求缓冲区,所有的访问请求都是按顺序执行的.Linux下的大多设备都是字符设备.应用程序是通过字符设备节点来访问字符设备的.设备节点一般都由mknod命令都创建在/dev目录下,下面的例子显示了串口设备的设备节点.字符设备文件的第一个标志是前面的“c”标志. root#ls -l /dev/ttyS[0-3]crw-

linux字符设备-自动创建设备号和设备节点

Linux字符设备-自动创建设备号和设备节点 先写一个自动分配字符设备号和设备节点的例子及APP 手动安装步骤: Insmod my_char_dev.ko 不需要再安装设备节点 然后是测试app ./my_char_dev_app 1 1 #include <linux/module.h> 2 #include <linux/init.h> 3 #include <linux/io.h> 4 #include <linux/fs.h> 5 #include

如何自动创建设备节点

创建设备文件的方法: 第一种是使用mknod手工创建:mknod filename type major minor 第二种是自动创建设备节点:利用udev(mdev)来实现设备文件的自动创建,首先应保证支持udev(嵌入式系统用mdev),由busybox配置. udev介绍 udev 运行在用户模式,而非内核中.udev 的初始化脚本在系统启动时创建设备节点,并且当插入新设备--加入驱动模块--在sysfs上注册新的数据后,udev会创新新的设备节点. udev 是一个工作在用户空间的工具,

platform型设备在/dev目录下自动创建设备节点的分析【转】

转自:http://blog.csdn.net/rockrockwu/article/details/7357648 系统启动过程中platform设备.驱动注册完毕,为什么在/dev目录下就自动创建好设备节点了? 在/dev目录自动创建设备节点可以通过class_create(),然后再device_create().但是在跟踪 内核platform注册过程中可以发现,其实这里面并未调用上诉两个函数,那么platform注册后 如何在/dev目录下创建设备文件节点? [cpp] view pl

字符设备设备节点创建的两种方法

在Linux下,字符设备和块设备都体现了"一切皆为文件"的思想,对于这两种设备而言,他们在Linux系统中都有一个对应的文件来"代表"它们的存在,那就是设备文件.应用程序通过操作某个设备文件,便可以操作对应的硬件.设备有主设备号和次设备号,例如在Linux下通过ls -l /dev/ttyS0命令可以看到如图信息 对于/dev/ttyS0设备文件,c表示它是一个字符设备文件(如果是'b'则是块设备文件),4是它的主设备号,64是它的次设备号.Linux系统根据设备文

自动创建设备节点class_create 和device_create

刚开始学习驱动的时候,每次都需要mknod /dev/timer c 500 0 这样手动去创建一个设备节点:实际上Linux内核提供一组函数,可以用来在驱动模块加载的时候自动在/dev目录下创建相应的设备节点,并在下载的时候删该节点. device_create(struct class *class, struct device *parent,dev_t devt, void *drvdata, const char *fmt, ...)和device_destroy(struct cla

Android udev /dev 设备节点权限

/************************************************************************* * Android udev /dev 设备节点权限 * 说明: * 现在的Linux系统设备节点权限一般都是通过动态配置,之前一直没找到具体 * 在哪里配置的说明,这次在看参考书的时候发现ueventd.rc就是用来做这件事的. * * 2016-5-14 深圳 南山平山村 曾剑锋 ********************************

I.MX6 linux eGalaxTouch 自动获取设备节点

I.MX6 linux eGalaxTouch 自动获取设备节点 \\\\\\\\\\\\\\-*- 目录 -*-///////////// | 一. 需求: | 二. /proc/bus/input/devices 内容: | 三. 解决方法: | 四. 实际应用: -------------------------------------- 一. 需求: 获取eGalaxTouch的输入设备节点 二. /proc/bus/input/devices 内容: [email protected]