简体   繁体   English

从内核空间执行用户空间功能

[英]Executing a user-space function from the kernel space

Im writing a custom device driver in linux that has to be able to respond very rapidly on interrupts. 我在Linux中编写了一个自定义设备驱动程序,该驱动程序必须能够非常快速地响应中断。 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? 但是我们要执行的代码是在用户空间中,是否有一种方法可以从内核空间模块中调用用户空间中的函数?

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 . 不过,您可以使用usermode-helper API从内核调用用户空间应用程序。 The following IBM DeveloperWorks article should get you started on using the usermode-helper Linux kernel API: 以下IBM DeveloperWorks文章应该使您开始使用usermode-helper Linux内核API:

Kernel APIs, Part 1: Invoking user-space applications from the kernel 内核API,第1部分:从内核调用用户空间应用程序

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. 您将需要了解内核调度程序的等待队列机制才能使用它。

Sounds like your interrupt line is already available to userspace via gpiolib? 听起来您的中断线已经可以通过gpiolib用于用户空间? (/sys/class/gpio/...) (/ sys / class / gpio / ...)

Have you benchmarked if gpio edge triggering and poll() is fast enough for you? 您是否对gpio边缘触发和poll()是否足够快进行了基准测试? That way you don't have to poll the status from the userspace application but edge triggering will report it via poll(). 这样,您不必从用户空间应用程序轮询状态,但是边缘触发将通过poll()报告状态。 See Documentation/gpio.txt in kernel source. 请参阅内核源代码中的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,设备节点等)将结果导出到用户空间。

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. 我也面临着同样的问题,我阅读了本文档http://people.ee.ethz.ch/~arkeller/linux/multi/kernel_user_space_howto-6.html ,因此计划使用信号。 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. 1.系统是闭环的,信号执行后,只有我会得到另一个信号。
2. And I am using POSIX real-time signals. 2.我正在使用POSIX实时信号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM