Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 用户空间与内核空间驱动程序_Linux_Linux Kernel_Linux Device Driver_Embedded Linux - Fatal编程技术网

Linux 用户空间与内核空间驱动程序

Linux 用户空间与内核空间驱动程序,linux,linux-kernel,linux-device-driver,embedded-linux,Linux,Linux Kernel,Linux Device Driver,Embedded Linux,我想写一个PWM驱动程序。我知道有两种方法可以控制硬件驱动程序: 用户空间驱动程序 内核空间驱动程序 如果一般(不考虑PWM驱动程序的情况),我们必须决定是去用户空间还是内核空间驱动程序。那么除了这些因素之外,我们还要考虑哪些因素呢 用户空间驱动程序可以直接将mmap()/dev/mem内存映射到其虚拟地址空间,无需进行上下文切换 用户空间驱动程序无法实现中断处理程序(它们必须轮询中断) 用户空间驱动程序无法执行DMA(因为可以从内核空间分配支持DMA的内存) 从你列出的三个因素中,只有第一个是

我想写一个PWM驱动程序。我知道有两种方法可以控制硬件驱动程序:

  • 用户空间驱动程序
  • 内核空间驱动程序
  • 如果一般(不考虑PWM驱动程序的情况),我们必须决定是去用户空间还是内核空间驱动程序。那么除了这些因素之外,我们还要考虑哪些因素呢

  • 用户空间驱动程序可以直接将mmap()/dev/mem内存映射到其虚拟地址空间,无需进行上下文切换
  • 用户空间驱动程序无法实现中断处理程序(它们必须轮询中断)
  • 用户空间驱动程序无法执行DMA(因为可以从内核空间分配支持DMA的内存)

  • 从你列出的三个因素中,只有第一个是正确的。至于其余的——不太可能。用户空间码可以执行DMA操作——这没有问题。有许多硬件设备公司在其产品中采用这种技术。也可以使用中断驱动的用户空间应用程序,即使所有的I/O都是通过完整的内核旁路完成的。当然,在
    /dev/mem
    上简单地执行
    mmap()
    并不是那么容易的

    您必须在内核中保留驱动程序的最小部分,这是为用户空间提供内核所需的最小部分所必需的(因为仔细想想,
    /dev/mem
    也由字符设备驱动程序备份)

    对于DMA来说,它实际上太容易了——您所要做的就是处理
    mmap
    请求并将DMA缓冲区映射到用户空间。对于中断-这有点棘手,无论发生什么,中断都必须由内核处理,但是,内核可能不做任何工作,只是唤醒调用的进程,例如,
    epoll\u wait()
    。另一种方法是像DOSEMU那样向流程发送信号,但速度非常慢,不建议这样做

    至于你的实际问题,你应该考虑的一个因素是资源共享。只要你不必在多个应用程序之间共享一台设备,并且在用户空间中没有你不能做的事情,那么就去用户空间吧。在开发周期中,您可能会节省大量的时间,因为编写用户空间代码非常容易。然而,当两个或多个应用程序需要共享设备(或其资源)时,您可能会花费大量时间来实现这一点——想象一下多个进程同时分叉、崩溃、映射(相同?)内存等。毕竟,IPC通常是通过内核完成的,所以,如果应用程序需要开始相互“对话”,那么性能可能会大大降低。不过,对于某些性能关键型应用程序,在现实生活中仍然可以这样做,但我不想详细介绍这些细节

    另一个因素是内核基础设施。假设您想编写一个网络设备驱动程序。在用户空间中这样做不是问题。但是,如果您这样做,那么您也需要编写一个完整的网络堆栈,因为不可能使用Linux内核中的默认堆栈


    如果可能的话,我会说使用用户空间,并且使事情正常工作的工作量比编写内核驱动程序要少,并且要记住,有一天可能需要将代码移动到内核中。事实上,根据是否定义了某个宏,为用户空间和内核空间编译相同的代码是一种常见做法,因为在用户空间中进行测试要愉快得多。

    另一个考虑因素:调试用户空间驱动程序要容易得多。您可以使用gdb、valgrind等。见鬼,您甚至不必用C编写驱动程序

    除了用户空间或内核空间驱动程序之外,还有第三种选择:两者都有。您可以在内核驱动程序中只执行内核空间的操作,也可以在用户空间中执行其他操作。如果使用LinuxUIO驱动程序框架,甚至可能不需要编写内核空间驱动程序(请参阅)

    我有幸在用户空间中编写了一个几乎完全支持DMA的驱动程序。UIO提供了基础设施,因此您可以在文件上读取/选择/epoll以等待中断


    您应该了解从用户空间编程DMA描述符的安全含义:除非您在设备本身或IOMMU中有一些保护,用户空间驱动程序可以使设备读取或写入物理内存中的任何地址。

    安全性:设备节点的文件权限控制用户可以打开/读取/写入设备的权限。文件操作拒绝或允许并发操作。决定可能在很大程度上取决于您正在使用什么,以及使用什么硬件。还要注意,您的内核代码必须放在GPL下。不过,epoll最后有一个快速机制,它是一个轮询结构,而不是一个中断处理程序。这可能会导致时间关键型操作出现问题。@obayhan您能详细说明时间关键型操作的投票问题吗?我使用这个“技巧”,我想知道更多。另外,VFIO似乎是取代UIO的全新机制: