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