1

我有一个生成数据的 Linux 内核模块,我想将该数据发送到用户空间应用程序。有哪些选择,它们有什么优点/缺点?

比方说,数据可能是每秒 100 个 char[] 和一些 int[] 的结构。

另外,如果可能(非强制性),我希望这些结构以与它们在 LKM 中生成的顺序相同的顺序到达用户空间。

4

2 回答 2

1

创建一个字符驱动程序并使用读取函数返回它。到目前为止,这方面绝对最好的教程是在LDD3(Linux 设备驱动程序,第三版)中,嘿!你可以免费下载!因此,您填写 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 获得系统调用号。:) 好吧,再说一次,如果您不尝试分发补丁,则不必这样做。字符驱动程序非常直接且易于实现。如果您希望用户态应用程序能够请求不同的数据并且仅在请求时返回该数据,您也可以使用 ioctl。或者,您可以让用户级应用程序编写一个请求,并且仅在它收到请求时从您的读取函数接收数据,但我假设您只想要一个恒定的数据喷射。在这种情况下,只需让您的读取函数写入(到用户空间)它从模块的任何部分获得的所有内容,并按照您想要发送的顺序。

再想一想,如果您正在处理大量数据并且遇到瓶颈,您可能需要考虑通过映射内存将其写入您的用户空间应用程序。但是,老实说,我在该特定领域没有很强的专业知识。

哦,是的,还请记住,您的 struct file_operations 函数可以休眠,而模块的其他部分可能不能。只是一个注释

于 2013-04-26T07:43:50.713 回答
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

于 2013-04-26T07:38:27.977 回答