Linux 从内核空间执行用户空间函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5246636/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 03:11:26  来源:igfitidea点击:

Executing a user-space function from the kernel space

clinuxmodulelinux-kernel

提问by S E

Im writing a custom device driver in linux that has to be able to respond very rapidly on interrupts. Code to handle this already exists in a user-space implementation but that is too slow as it relies on software constantly checking the state of the interrupt line. After doing some research, I found that you can register these interrupt lines from a kernel module, and execute a function given by a function pointer. However the code we want to execute is in the user-space, is there a way to call a function in the user-space from a kernel space module?

我在 linux 中编写了一个自定义设备驱动程序,它必须能够非常快速地响应中断。处理此问题的代码已存在于用户空间实现中,但速度太慢,因为它依赖于软件不断检查中断线的状态。经过一番研究,我发现您可以从内核模块注册这些中断线,并执行由函数指针给出的函数。然而,我们要执行的代码在用户空间中,有没有办法从内核空间模块调用用户空间中的函数?

采纳答案by Shinnok

You are out of luck with invoking user-space functions from the kernel since the kernel doesn't and isn't supposed to know about individual user-space application functions and logic, not to mention that each user-space application has it's own memory layout, that no other process nor the kernel is allowed to invade in that way(shared objects are the exception here, but still you can't tap into that from the kernel space). What about the security model, you aren't supposed to run user-space code (which is automatically considered unsafe code in the kernel context) in the kernel context in the first place since that will break the security model of a kernel right there in that instant. Now considering all of the above mentioned, plus many other motives you might want to reconsider your approach and focus on Kernel <-> User-space IPC and Interfaces, the file system or the user-mode helper API(read bellow).

从内核调用用户空间函数是不走运的,因为内核不知道也不应该知道单个用户空间应用程序的功能和逻辑,更不用说每个用户空间应用程序都有自己的内存布局,不允许其他进程或内核以这种方式侵入(共享对象是这里的例外,但您仍然无法从内核空间利用它)。那么安全模型呢,你不应该首先在内核上下文中运行用户空间代码(在内核上下文中它被自动认为是不安全的代码),因为这会破坏内核的安全模型那一瞬间。现在考虑到上述所有内容,再加上许多其他动机,您可能想要重新考虑您的方法并专注于内核 <->IPC 和接口、文件系统或用户模式助手 API(请阅读下文)。

You can invoke user space apps from the kernel though, that using the usermode-helper API. The following IBM DeveloperWorks article should get you started on using the usermode-helper Linux kernel API:

不过,您可以使用usermode-helper API从内核调用用户空间应用程序。以下 IBM DeveloperWorks 文章应该让您开始使用 usermode-helper Linux 内核 API:

Kernel APIs, Part 1: Invoking user-space applications from the kernel

内核 API,第 1 部分:从内核调用用户空间应用程序

回答by kauppi

Sounds like your interrupt line is already available to userspace via gpiolib? (/sys/class/gpio/...)

听起来您的中断线已经可以通过 gpiolib 提供给用户空间了?(/sys/class/gpio/...)

Have you benchmarked if gpio edge triggering and poll() is fast enough for you? That way you don't have to poll the status from the userspace application but edge triggering will report it via poll(). See Documentation/gpio.txt in kernel source.

您是否对 gpio 边缘触发和 poll() 是否足够快进行了基准测试?这样你就不必从用户空间应用程序轮询状态,但边缘触发将通过 poll() 报告它。请参阅内核源代码中的 Documentation/gpio.txt。

If the edge triggering via sysfs is not good enough, then the proper way is to develop a kernel driver that takes care of the time critical part and exports the results to userspace via a API (sysfs, device node, etc).

如果通过 sysfs 触发的边缘不够好,那么正确的方法是开发一个内核驱动程序来处理时间关键部分,并通过 API(sysfs、设备节点等)将结果导出到用户空间。

回答by MarkR

I think the easiest way is to register a character device which becomes ready when the device has some data.

我认为最简单的方法是注册一个字符设备,当设备有一些数据时它就准备好了。

Any process which tries to read from this device, then gets put to sleep until the device is ready, then woken up, at which point it can do the appropriate thing.

任何尝试从该设备读取的进程,然后进入睡眠状态,直到设备准备就绪,然后被唤醒,此时它可以做适当的事情。

If you just want to signal readyness, a reader could just read a single null byte.

如果您只想表示准备就绪,阅读器可以只读取一个空字节。

The userspace program would then just need to execute a blocking read() call, and would be blocked appropriately, until you wake it up.

然后用户空间程序只需要执行一个阻塞的 read() 调用,并且会被适当地阻塞,直到你唤醒它。

You will need to understand the kernel scheduler's wait queue mechanism to use this.

您需要了解内核调度程序的等待队列机制才能使用它。

回答by duslabo

I am also facing the same problem, I read this document http://people.ee.ethz.ch/~arkeller/linux/multi/kernel_user_space_howto-6.html, so planning to use signals. In my case there is no chance of losing signals, because
1. the system is closed loop, after signals executed then only I will get another signal.
2. And I am using POSIX real-time signals.

我也面临同样的问题,我阅读了这个文档http://people.ee.ethz.ch/~arkeller/linux/multi/kernel_user_space_howto-6.html,所以打算使用信号。在我的情况下,没有丢失信号的机会,因为
1. 系统是闭环的,在信号执行后只有我会得到另一个信号。
2. 我使用的是 POSIX 实时信号。