我很难理解何时应该编写设备驱动程序,而不是仅仅通过{user}空间程序通过outb
将硬件代码直接发送到硬件。我最初认为我应该为硬件创建简单的例程,但现在我开始认为算法应该保留在用户空间中。
假设我正在编程一个假想的机器人手臂。我可以在Linux内核模块中编写几个函数,这些函数可以自动执行常见任务所需的硬件输出(例如,将arm移动到HOME位置,从装配线开始处的已知位置拾取新块等)。然而,在阅读了有关设备驱动程序的更多信息之后,似乎经验法则是尽可能使设备驱动程序尽可能接近特定于硬件的代码,将“繁重的”算法留给用户空间。
这让我感到困惑,因为如果设备驱动程序实现的唯一功能是简单的操作码调用,那么用户空间程序使用设备文件而不是直接调用outb
/ inb
的原因是什么?
我想我想弄清楚的是:我如何决定内核空间而不是用户空间中的功能?
答案 0 :(得分:9)
好问题。我已经和那个人搏斗了 - 我甚至写过控制机器人手臂的司机,当我知道这个事实没有必要时。我可以通过串口或outb()等轻松发送命令。我只是为了教育目的而编写这些驱动程序。
设备驱动程序有很多充分的理由。想象一下,尝试直接从用户空间控制您的网卡!首先,驱动程序在操作系统级别(eth0等)为您提供了一个很好的抽象。但是,从性能的角度来看,尝试处理用户空间中数据包发送/接收的中断将是非常不切实际的 - 甚至可能是不可能的。只需要在用户空间中响应中断所花费的时间就会将界面拖到膝盖上。
想象一下,你买了一张新的网卡。加载新驱动程序并继续从用户空间与eth0交谈而不更改代码不是很好吗?
所以,如果你没有看到需要,我会说“写一个驱动程序没有意义”。我认为驱动程序的存在是由需求驱动的(如在NIC驱动程序示例中),而不是相反。
听起来对你的应用来说,outb()比创建驱动程序要简单得多。最后,我甚至没有使用我的机器人手臂驱动程序 - 只需将字节写入串口也能正常工作 - 只需要几行代码; - )
答案 1 :(得分:8)
如果在用户空间中使用outb
和inb
,那么您的用户空间将是x86特定的 - 用户空间outb()
和inb()
宏是使用x86程序集实现的。另一方面,如果编写内核驱动程序,而驱动程序将在任何支持PCI的架构上运行,则内核中的inb()
和outb()
函数将以特定于体系结构的方式实现。内核还为您提供request_region()
等功能,以确保您的IO端口不会与任何其他驱动程序冲突。
此外,您的用户空间驱动程序需要以root用户身份运行(或者技术上具有CAP_SYS_RAWIO
功能,这是root用户身份。内核中的字符设备驱动程序意味着您可以使用字符设备文件上的UNIX权限来控制哪些用户空间用户可以访问该设备。
答案 2 :(得分:2)
设备驱动程序必须仅实现处理硬件的机制(与操作系统无关)。 解决方案的所有智能必须存在于用户空间中。
是的,您可以在用户空间中执行所有操作,但是:
它不可重复使用;其他用户空间程序必须重新实现机制才能访问机械臂(例如)
表现不佳;它取决于应用程序,也许它不是机器人手臂的问题(很慢),但它可能是网卡,磁盘,图形卡的问题
因此,对于机器人手臂,您应该在驱动程序中实现该机制(移动电机,从传感器获取信息)。因此,您的程序和其他程序可以使用驱动程序使手臂变得聪明。聪明的东西是由用户空间程序完成的:绘制Gioconda,准备蛋糕,小心移动炸药。驱动程序是基本功能的实现,允许用户使用硬件。
但很明显,这取决于硬件和环境。