Device Management

来自osdev
(重定向自Device Driver Interfaces
跳到导航 跳到搜索

所有现代操作系统都有一个称为设备管理器(device manager)的子系统。 设备管理器负责检测和管理设备,执行电源管理以及将设备暴露给用户空间。 由于设备管理器是任何操作系统的关键部分,因此确保其设计良好非常重要。

设备驱动程序

设备驱动程序允许用户应用程序与系统的设备间进行通信。 它们为用户应用程序提供硬件的高级抽象,同时处理低级设备特定的I/O和中断。 设备驱动程序可以实现为可加载的内核模块 (对于 Monolithic Kernel) 或用户模式服务 (对于 Microkernels)。

设备检测

设备管理器的主要作用是检测系统上的设备。 通常,设备以树形结构组织,设备可以枚举其子设备。 设备检测应以 “根总线驱动程序root bus driver” 开始。在x86系统上,根总线驱动程序将使用 ACPI。 根总线驱动程序位于设备树的根。 它检测系统上存在的总线以及直接连接到主板的设备。 然后对每条总线进行递归枚举,其子总线继续枚举其子总线,直到到达设备树的底部为止。

检测到的每个设备都应包含供设备使用的资源列表。 资源的示例是I/O,内存,IRQs,DMA通道和配置空间。 设备由其父设备分配资源。 设备应该只使用它们提供的资源,这为使相同的设备驱动程序在资源分配可能不同的不同机器上工作提供了支持,但编程接口在其他方面是相同的。

为找到的每个设备加载驱动程序。 当检测到设备时,设备管理器会找到该设备的驱动程序。 如果尚未加载,则设备管理器将加载驱动程序。 然后它调用驱动程序来初始化该设备。

设备管理器如何将设备与设备驱动程序匹配是一个重要的选择。 识别设备的方式非常特定于总线。 在 PCI 上,通过其供应商和设备id的组合来识别设备。 USB 具有与PCI相同的方案,使用供应商和产品ID。 ACPI 使用PNP ID来识别ACPI命名空间中的设备。 有了这些信息,就可以使用与驱动程序匹配的id来构建一个数据库。 此信息最好存储在单独的文件中。

进程间通信 (IPC)

设备管理器需要在它和设备驱动程序之间实现某种形式的IPC。 设备管理器将使用IPC向设备驱动程序发送I/O请求,并由设备驱动程序响应这些请求。 通常使用包含有关请求的数据的消息来实现,例如I/O函数代码,缓冲区指针,设备偏移量和缓冲区长度。 为了响应这些I/O请求,每个设备驱动程序都需要用于处理每个I/O功能代码的分派功能。 每个设备都需要这些IPC消息的队列才能处理。 在Windows NT上,此IPC是使用I/O请求数据包完成的。

异步 I/O

I/O主要有两种类型: 同步I/O和异步I/O。 同步I/O发送I/O请求,然后将当前线程置于休眠状态,直到I/O完成。 异步I/O只是发送I/O请求,然后返回。 使用回调异步报告I/O完成。 异步I/O通过允许在执行I/O时继续执行程序来提高系统的效率。 它还允许启动多个I/O请求,然后按照它们完成的顺序而不是它们执行的顺序进行处理。 但是,这是以使编程比使用同步I/O更加复杂为代价的。

在内部,操作系统应该对其所有I/O请求使用异步I/O。 I/O请求被发送到驱动程序,然后发送它们的函数立即返回。 最终,将处理I/O请求。 一旦完成,它将通过驱动程序堆栈返回,并最终通知应用程序I/O完成。 它可以使用回调、信号或完成队列来做到这一点。

同步I/O可以简单地实现为不同步I/O的特殊情况。 就像异步I/O一样,I/O请求被发送到驱动程序,但是线程没有返回而是进入睡眠状态。 一旦I/O完成事件排队,线程将唤醒并在返回之前执行回调。

电源管理

设备管理器还执行电源管理。 电源管理是硬件的一项功能,它允许控制系统和设备的功耗。 由设备管理器管理的每个设备都应提供设置其电源状态的功能。 对于电源管理支持,所有系统都需要控制系统电源的电源管理驱动程序。 在x86上,这是通过 ACPI 完成的。 每个设备还需要支持电源管理。

设备管理器需要响应电源管理事件。 电源管理事件可以来自两个来源: 用户或系统。 用户生成的电源管理事件由用户模式应用程序创建。 它们是系统范围内的事件,用于关闭,重新启动,休眠或使系统进入睡眠状态。 当设备管理器接收到系统范围的电源管理事件时,它设置系统的电源状态。

系统生成的电源管理事件是来自系统硬件的事件。 系统生成的电源管理事件的示例是插入/拔出AC适配器或关闭/打开笔记本电脑的盖子。 设备管理器响应事件采取适当的操作。

用户空间曝光

设备驱动程序的内核接口完成后,还需要弄清楚如何将设备暴露于用户空间。 大多数基于Unix的操作系统通过文件系统树公开设备。 当设备放置在文件系统树中时,有一个目录 (通常是/dev) 包含表示设备的特殊文件。 将设备放置在文件系统树中的优点是可以将设备视为文件,这意味着可以从中读取或写入设备。 Windows NT不会通过文件系统树公开设备。 取而代之的是,有一个对象的内部命名空间,通过它可以像文件一样找到和访问设备。

无论如何暴露设备,也必须确定为设备提供的功能。 基于Unix的操作系统和Windows NT都将设备视为文件,这意味着它们的功能是open(),close(),read() 和write()。 但是,很快就意识到此API不适用于一些特殊功能的设备功能,例如设置视频卡的图形模式。 为此,开发了一种名为ioctl() 的新syscall,它允许设备具有特殊功能。 但是,这绝不是调用设备功能的唯一方法。

现有驱动程序接口

操作系统不需要实现自己的驱动程序接口。 一些驱动程序接口已经被编程,目的是集成到操作系统中。 这些驱动程序接口可以代替本机驱动程序接口、在本机驱动程序接口之上或与本机驱动程序接口一起实现。

统一驱动接口

正文: Uniform Driver Interface

Project UDI是一个驱动程序接口,旨在在不同的CPU体系结构上运行时是二进制可移植或源可移植的。 它不是很普遍 (但是,EDI或CDI都不是); 例如,由于哲学上的担忧,Linux没有接受UDI。 但是,社区中的一些成员正在努力再次普及UDI,因为这将对爱好者的操作系统产生巨大的好处。 强烈建议您加入UDI环境并编写驱动程序。

可扩展驱动程序接口

正文: Extensible Driver Interface

EDI是一个驱动程序界面,旨在可移植源代码,并且在实现上相当简单 (功能有限),因此爱好者那些小操作系统可以共享驱动程序代码库。

另见

External Links