设备驱动程序和Windows

8
我正在努力完善PC和操作系统之间的交互方式。在设备驱动程序方面,我有些疑惑。请不要说这太复杂或者在使用高级编程语言和WinAPI函数时不需要了解这些内容。我想要学习,因此希望了解这些内容。
基本上,我认为操作系统和PC(指硬件)之间的关系结构是:除了CPU可以自己执行的直接CPU命令(算术运算、寄存器访问和内存访问)外,所有其他命令都必须通过操作系统。主要是因为从第三个环级别开始,您无法使用用于访问其他硬件的in和out指令。我知道有MMIO,但必须先通过端口通信设置它。
并非一直如此。即使我有点年轻,不记得MSDOS,我也知道你可以直接访问硬件,因为没有限制,没有环模式。因此,您可以使用天气DOS功能将字符串写入显示器,或者直接访问视频卡内存并自己编写它。
但随着操作系统的发展,就不再存在这种可能性。但这没关系,因为现在操作系统处理所有硬件通信,并且在多任务环境中更方便、更安全(我会说是唯一的选择)。因此,现在您不需要使用int指令来使用BIOS映射功能或DOS功能,而是调用dll,其内部处理了您不需要了解的所有内容。
我理解这一点。我也理解设备驱动程序是在第0个环级别运行的代码片段,因此它可以执行所有硬件交互。但我不理解操作系统和设备驱动程序之间的连接。让我们举个例子——我想让声卡发出声音。因此,我调用Windows API来访问声卡,但接下来会发生什么呢?Windows会调用设备驱动程序来完成吗?
但如果它确实调用设备驱动程序,那么是否意味着所有可以通过WinAPI函数调用的设备驱动程序都必须具有以某种特定方式命名的例程?我的意思是,当我有新的声卡时,它的驱动程序必须与旧的驱动程序具有相同的函数名称吗?因此,从Windows的角度来看,Windows可以调用相同的函数吗?但是,如果Windows预定义了设备驱动程序所需的一组函数,那么它不能使用以前版本中不存在的新驱动程序。
请帮助我理解这个混乱。我真的很疯狂。谢谢。
2个回答

11
一个Windows设备驱动程序类似于DLL,但与其由应用程序进行动态链接/加载不同,是操作系统进行动态链接/加载。
注册表条目告诉操作系统存在哪些设备驱动程序(以便操作系统知道要动态链接/加载哪些设备驱动程序)。
设备驱动程序在ring 0中运行。在ring zero中,它们(设备驱动程序)无法访问(不能链接或使用)Windows API,而是可以访问各种NT内核API。
基本上是这样的,所有同一类型或类别(例如所有视频驱动程序或所有磁盘驱动程序)的设备驱动程序都有相似的API,由操作系统调用(和/或由更高级别的驱动程序调用,例如磁盘驱动程序由文件系统驱动程序使用/调用)。
Windows设备驱动程序包定义了各种API,并包括各种类型设备的示例驱动程序。
操作系统正在动态链接到设备驱动程序函数:由于设备驱动程序API是预定义的,对于操作系统而言设备驱动程序是可互换的;可以编写新的设备驱动程序,只要它们支持(向后兼容)标准设备驱动程序API。
动态链接机制非常类似于COM对象或C++类实现任何预定义的纯抽象接口的方式:DDK中的头文件声明纯抽象接口(如虚函数),设备驱动程序实现这些函数,操作系统加载驱动程序并调用这些函数。

谢谢,好的回答。我可以再问一个问题吗?如果我理解正确,对于操作系统“已知”的设备,有预定义的函数名称集合,因此无论使用哪个控制器进行HDD访问(SCSI,SATA,ATA等),操作系统都可以调用例如“get_sector()”函数。但是,如果我有全新的设备,操作系统无法通过WinAPI操纵它,我是否仍然可以为其编写驱动程序,然后从我的程序中调用它们?谢谢。 - B.Gen.Jack.O.Neill
@b-gen-jack-o-neill - 是的:Windows应用程序可以使用DeviceIoControl函数向设备驱动程序发送/接收任意数据。 - ChrisW
@ChrisW 确实非常有见地。但是,“设备驱动程序在ring 0中运行。” - 内核不仅在ring 0中运行,设备驱动程序也在ring 1和2中运行,对吗? - KeyC0de
1
@KeyC0de 我引用了https://en.wikipedia.org/wiki/Protection_ring#Privilege_level的内容--“并不需要使用所有四个特权级别。目前市场占有率较高的操作系统,包括Microsoft Windows,macOS,Linux,iOS和Android,大多使用分页机制,只有一个位来指定特权级别,即监管员或用户(U/S位)。Windows NT使用两级系统。”我的回答基于我在1990年代为Windows NT编写设备驱动程序等方面的经验。 - ChrisW

0

基础知识: 请注意,这个解释是简化的,有时只适用于大多数情况而不是全部。

你将遇到的大多数硬件设备都具有以下基本操作: 在它们上面写入内存(或寄存器)。 从它们上面读取内存(或寄存器)。

这已足以控制硬件,为其提供所需数据,并从中获取所需数据。

这些内存区域由BIOS和/或操作系统映射到PC上的物理内存范围(可能由驱动程序访问)。

因此,我们现在有了两个操作:读取和写入,设备驱动程序知道如何执行这些操作。

此外,驱动程序可以以不涉及CPU的方式进行读写。这称为直接内存访问(DMA),通常由您的硬件执行。

最后一种操作称为中断,用于让您的硬件通知驱动程序发生了某些事情。这通常是通过硬件中断CPU并调用您的驱动程序以高优先级执行某些操作来完成的。例如:硬件准备好要由驱动程序读取的图像。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接