我有一个生成数据的Linux内核模块,我想将这些数据发送到用户空间应用程序。有哪些选择以及它们有哪些优点/缺点?
可以说,数据可以是每秒100个char []和几个int []的结构。
此外,如果可能(非强制性),我希望这些结构以与在LKM中生成的顺序相同的顺序进入用户区。
答案 0 :(得分:1)
您可以尝试传递包含缓冲区指针和结构的结构。缓冲区的大小。但是同样的结构也应该在用户空间应用和定义中定义。在你的系统调用内核中的代码。
struct new_struct
{
void *p; //set this pointer to your buffer...
int size;
};
//from user-application...
int main()
{
....
struct new_struct req_kernel;
your_system_call_function(...,(void *)&req_kernel,...);
// here u can get the data which is copied from kernel-space in req_kernel structure.
}
........................................................................................
//this is inside your kernel...
your_system_call(...,char __user optval,...)
{
.....
struct new_struct req;
// fill the data in the resq structure. which will be access in user-space.
if (copy_to_user(&req, optval, sizeof(req)))
return -EFAULT;
//now you have the address or pointer & size of the buffer
//which you want in kernel with struct req...
}
请参阅http://people.ee.ethz.ch/~arkeller/linux/kernel_user_space_howto.html
答案 1 :(得分:1)
创建一个字符驱动程序并使用read函数返回它。到目前为止,绝对最好的教程是LDD3 (Linux Device Drivers, Third Edition),嘿!你可以免费下载!所以你填写你的struct file_operations并填充这些字段:
static const struct file_operations my_fops = {
.owner = THIS_MODULE,
.read = my_read,
.open = my_open,
.release = my_release,
};
将那只小狗传递给cdev_init()等等。这就是你吐出数据的地方(在my_read()中)
编辑:噢,是的,我拥有这本书的实体书,这绝对是我用过的最常用的,随身携带等等。EDIT2:啊,所以你想要专业人士现在缺点呃? :)我会说,角色驱动程序的最大专业是你不必从Torvolds获得一个系统调用号码。 :)那么,再说一次,如果你不试图发布你的补丁,你不必这样做。字符驱动程序非常简单,易于实现。如果您希望userland应用程序能够请求不同的数据并且仅在请求时返回该数据,您还可以使用ioctl。或者,您可以让userland应用程序写入请求,并在收到请求时仅从读取函数接收数据,但我认为您只需要持续的数据溢出。在这种情况下,只需让你的读取函数写入(到userland)它从模块的任何部分获得的所有内容,因为它获取它并按照你想要发送它的顺序。
还有一种想法,如果您处理大量数据并遇到瓶颈,您可能需要考虑通过mmaped内存将其写入用户空间应用程序。但是,老实说,我并没有那个特定领域的专业知识。
哦,是的,还要记住你的struct file_operations函数可以睡眠,也许你的模块的其他部分不能。只是一个注释