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

发布于 2024-08-30 00:56:41 字数 280 浏览 10 评论 0原文

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

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

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

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

Is it possible to expand the ioctl interface in Linux so that the user-space application can send a pointer to a function to the kernel space driver?

I'm in particular thinking of ways to handle the stream in user-controllable way but doing it in the kernel. Those operations could be attached to the kernel module but this would make development a lot easier as I wouldn't need to mess with the kernel during development.

More specifically, this would be the process:

  1. Data is read by the driver to a buffer.
  2. Data is handled by these user-defined functions in place.
  3. Some more handling is done, possibly with some HW blocks.
  4. Data is used by a user-space application.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

强者自强 2024-09-06 00:56:41

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

然后你可以使用 inotify (Linux 期刊文章)用于内核->用户空间事件通信。 Ioctl 或写入设备以进行用户空间->内核事件通信。数据交换也可以通过读/写一个或多个设备文件来实现。

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

您也可以考虑 ksocket

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

I think you can achieve what you want by having your driver provide one or more character devices (or block devices) that your user space applications opens.

Then you could use inotify (linux journal article) for kernel->user space event communication. Ioctl or writing to the device for user space->kernel event communication. Data exchange could also be achieved by reading/writing to one or more device files.

Alternatively you can provide /proc or /sys filesystem entries or use netlink.

You might also consider ksocket:

Ksocket is a linux 2.6 kernel module
that provides bsd-style socket
interfaces (namely socket, bind,
listen, connect, accept, ...) for
kernel developers to facilitate their
network progaramming in linux kernel
space.
The interfaces ksocket presents are much the same as their equivalent
in glibc, so even new developers for
kernel space will have no barrier in
developing kernel network-related
programms.

南城追梦 2024-09-06 00:56:41

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

I think you're asking for a square circle: if the kernel were to just execute your "userland" function directly, it wouldn't be "userland" but rather a homebrew loadable module system. I assume that what you really want is a way to figure out what to do to make it all work without crashing your PC every time you make a mistake. Maybe you could abuse signal handlers as the means of "callback", but I'm too rusty to point out how you'd get back to the kernel as if by a function call return. The problem here is that in any userland->kernel context switch, the kernel starts with a fresh stack, so the return address is long gone. How about if you combine a signal handler with mmap'ing /dev/mem, and let your userland pseudodriver poke the kernel-mode driver's data structures directly? But then you're back to rebooting when you make a mistake, unless you figure out how to mmap only your driver's data structures? Other repurposeable mechanisms might be STREAMS and TTY line disciplines; I think these confer some sort of transmogrifying ability. Of course none of this is a good idea as a permanent solution!

烟凡古楼 2024-09-06 00:56:41

您的用例不断提及数据。

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

Your use case keeps mentioning data.

Maybe what you want to do is share memory between the kernel and a user process. You could put data and/or commands into the shared memory, and the process/kernel code on the other side could read it and do whatever. The get_user_pages_fast() call can make a process's memory accessible to the kernel, even when the process is not currently running.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文