是否可以从Linux(ioctl)中的内核空间调用用户空间回调函数?

时间:2010-04-22 10:29:58

标签: linux-kernel kernel linux-device-driver ioctl

是否可以在Linux中扩展ioctl接口,以便用户空间应用程序可以向内核空间驱动程序发送指向函数的指针?

我特别想到了以用户可控方式处理流但在内核中执行流的方法。这些操作可以附加到内核模块,但这会使开发变得更容易,因为我不需要在开发期间搞乱内核。

更具体地说,这将是一个过程:

  1. 驱动程序将数据读取到缓冲区。
  2. 数据由这些用户定义的函数处理。
  3. 完成了一些处理,可能还有一些HW块。
  4. 数据由用户空间应用程序使用。

3 个答案:

答案 0 :(得分:8)

我认为您可以通过让驱动程序提供用户空间应用程序打开的一个或多个角色设备(或块设备)来实现您的目标。

然后,您可以使用inotifylinux journal article)进行内核与用户空间事件通信。 Ioctl或写入设备以进行用户空间 - >内核事件通信。也可以通过读/写一个或多个设备文件来实现数据交换。

或者,您可以提供/ proc或/ sys文件系统条目或使用netlink。

您可能还会考虑ksocket

  

Ksocket是一个linux 2.6内核模块   提供bsd风格的套接字   接口(即socket,bind,   听,连接,接受,...)   内核开发人员方便他们   linux内核中的网络progaramming   空间。       接口ksocket存在与它们的等价物大致相同   在glibc,所以即使是新的开发人员   内核空间将没有障碍   开发与内核网络相关的   programms的。

答案 1 :(得分:4)

我认为你要求一个方圆:如果内核只是直接执行你的“userland”函数,它就不是“userland”而是一个自制的可加载模块系统。我认为你真正想要的是一种方法来弄清楚如何使它全部工作,而不会在每次出错时崩溃你的电脑。也许你可以滥用信号处理程序作为“回调”的手段,但是我太生疏了,无法指出你如何通过函数调用返回返回到内核。这里的问题是,在任何userland->内核上下文切换中,内核都以新堆栈开始,因此返回地址早已消失。如果你将信号处理程序与mmap'ing / dev / mem结合起来,让你的userland伪驱动程序直接戳到内核模式驱动程序的数据结构怎么样?但是当你犯错误时,你会重新启动,除非你弄清楚如何mmap 你的驱动程序的数据结构?其他可重复使用的机制可能是STREAMS和TTY线路规则;我认为这些赋予某种变形能力。当然,这不是一个永恒的解决方案!

答案 2 :(得分:2)

您的用例一直在提及数据。

也许您想要做的是在内核和用户进程之间共享内存。您可以将数据和/或命令放入共享内存中,另一方的进程/内核代码可以读取它并执行任何操作。 get_user_pages_fast()调用可以使内核可以访问进程的内存,即使进程当前没有运行。