答案1
非常简单地说:
设备驱动程序最重要的是它运行在内核空间,具有与内核相同的权限,因此可以直接访问硬件。应用程序(通常)不允许这样做。
因此,您可以将设备驱动程序视为组织对某些硬件(“设备”)的访问的内核部分。
应用程序可以在各个级别上与内核交互:从较高的抽象(例如文件系统)到中等抽象(块设备)再到真正的低级抽象(一些文件在/proc/
或中/sys
,一些ioctls
在设备中/dev
)。因此,低级交互有时会非常直接地与设备驱动程序对话,只有一个非常薄的层,内核将调用重定向到设备驱动程序。因此,“应用程序无法直接与设备驱动程序交互,只有操作系统可以做到这一点”是正确的,也是错误的。
此外,内核中有许多抽象层,就像您在图片中描述的那样(“操作系统发送的消息是相同的,设备驱动程序使用不同的消息与硬件通信)。例如,块层接收一个USB 层接收一种消息,但可以使用不同的 USB 主机控制器,依此类推。
因此,情况要困难得多,内核中有层和子系统,而实际与硬件通信的设备驱动程序位于该层次结构的底部。更令人困惑的是,设备驱动程序和其他层都以模块的形式出现(对于 Linux)。如果您键入lsmod
,您可以查看哪些模块处于活动状态,以及哪个模块使用哪些其他模块。
另外,印刷是一个非常糟糕的例子。大多数特定于打印机的处理发生在用户空间中,而不是在设备驱动程序中。
Windows、Linux 和 MacOS 都遵循这些原则,但细节有很大不同。
这有帮助吗?
编辑:
如今,Linux 上的打印通常是通过杯子。 Cups 有一系列程序可以为各种打印机渲染文档。所有这些程序都会获取一个文件(文档为 pdf/postscript/...)并将其转换为打印机可以理解的格式的另一个文件。所有这些都发生在内核之外,因为这些都不需要访问实际的硬件。它只是读取和写入文件。只有最后一部分,即当转换后的数据发送到打印机时,才使用内核。然后它可以使用各种路径,甚至对于同一类型的打印机:通过网络、通过 USB、通过串行连接等。最后一部分通常不是特定于打印机的。
因此,Linux 并没有真正为大多数打印机提供特定于打印机的设备驱动程序。 (对于几台打印机,您可能需要一台)。
答案2
设备驱动程序只是操作系统和设备之间的“中间人”。
是的,或多或少就是这样。
设备驱动程序是将标准化编程调用转换为硬件组件的设备特定操作的“黑匣子”。
这样,程序不需要知道特定硬件的内部工作原理;特定的设备驱动程序将以透明的方式进行映射,允许程序与硬件“对话”。
它们是与内核分开构建的,并在需要时激活(作为模块加载到内核中)。