【问题标题】:Is it possible to call a user-space callback function from kernel space in Linux (ioctl)?是否可以从 Linux (ioctl) 的内核空间调用用户空间回调函数?
【发布时间】:2011-02-11 00:14:40
【问题描述】:

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

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

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

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

【问题讨论】:

  • 在内核空间运行用户提供的代码会在系统中打开一个巨大的安全漏洞。
  • 我知道,但即使这只是用于初始开发,它也会非常有用。
  • @stsquad 我不认为他想在内核上下文中运行用户模式代码,而是从用户代码调用他的系统调用,将回调处理程序指针传递给它,内核返回给用户-mode 每次调用它,所以它看起来就像从用户代码的角度来看的常规回调。
  • 这就是我的想法,j_kubik。

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


【解决方案1】:

我认为你可以通过让你的驱动程序提供一个或多个字符设备(或块设备)来让你的用户空间应用程序打开来实现你想要的。

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

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

你也可以考虑ksocket:

Ksocket 是一个 linux 2.6 内核模块 提供 bsd 风格的套接字 接口(即套接字,绑定, 听,连接,接受,...) 内核开发人员以方便他们的 linux内核中的网络编程 空间。 ksocket 提供的接口与它们的等效接口非常相似 在 glibc 中,所以即使是新开发人员 内核空间将没有障碍 开发内核网络相关的 程序。

【讨论】:

  • 好吧,显然我可以将数据发回,但如果我们谈论高速通信(如音频数据),这将有助于将大量数据复制到整个地方......
【解决方案2】:

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

【讨论】:

  • 我总是可以在虚拟机中运行开发系统,所以崩溃并不是这里真正的问题。
【解决方案3】:

您的用例不断提及数据。

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

【讨论】:

    猜你喜欢
    • 2017-12-10
    • 2012-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多