用户空间和内核线程之间的共享内存

6
我正在开发一个内核应用程序,其中涉及到kthreads。我在用户空间创建了一个结构体数组并使用malloc分配了内存。然后我调用一个系统调用(我实现的),并将数组地址传递给内核空间。在系统调用的处理程序中,我创建了2个kthread来监视该数组。kthread可以更改一些值,用户空间线程也可以更改一些值。这个想法是将数组用作共享内存。但是当我在内核空间访问内存时(使用copy_from_user),数据会以某种方式更改。我可以验证赋值和内核中的地址是相同的。但是使用copy_from_user时,它会给出各种值,如垃圾值。
另外,以下语句是否正确?
int kthread_run_function(void* data){
    struct entry tmp;
    copy_from_user(&tmp, data, sizeof(struct entry));
}
2个回答

9
这样做是不正确的,因为copy_from_user()从当前用户进程中复制(这应该是显而易见的,因为无法告诉它从哪个用户进程中复制)。
在由用户空间进程调用的系统调用中,这是可以的,因为当前进程是用户空间进程。然而,在内核线程中,当前进程可以是系统上的任何其他进程 - 因此,您正在从随机进程的内存中复制,这就是为什么会出现垃圾值的原因。
如果您想在内核和用户空间进程之间共享内存,则正确的方法是让内核分配它,然后允许用户空间进程使用mmap()将其映射到其地址空间中。内核线程和用户空间进程将使用不同的指针来引用内存区域 - 内核线程将使用指向内核地址空间中分配的内存的指针,而用户空间进程将使用指向mmap()返回的内存区域的指针。

你说得完全正确。我一直在考虑从系统调用中保存上下文,并将此上下文用于copy_from_user,但我想这可能不太合适。我也在考虑mmap。你能给我提供一个在Linux内核2.6中可行的示例吗? - max
@max,请问你找到这方面的例子了吗?我也遇到了同样的问题,但是没有找到如何在内核空间分配内存并使用mmap将其映射到用户空间的任何资料。 - gaston

1

不行,通常情况下不可以,因为data是内核虚拟地址,而不是用户虚拟地址。

但是,如果你使用kthread_create函数并将data参数设置为一个__user指针,那么这应该是可以的。


1
我尝试过这个,但是没有起作用。当我从内核空间的kthread访问用户空间指针时,我遇到了麻烦。我可以在系统调用函数中访问内存,但在kthread函数中无法访问它。我的简单问题是如何在kthreads和用户空间之间获取共享内存。 - max
你不能仅仅将用户指针塞入内核线程中。这在与用户进程不同的任务上下文中是*毫无意义的。 - Jörgen Sigvardsson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接