2

我想将用户空间内存中的指针传递到内核模块中的函数中。我不想使用copy_from_user. 我读过我应该使用get_user_pages函数。

例如一页。

struct page **pages;
pages = kmalloc(1 * sizeof(*pages), GFP_KERNEL);

down_read(&current->mm->mmap_sem);
get_user_pages(current,current->mm,uaddr, 1, 1, 0,pages,NULL);
up_read(&current->mm->mmap_sem);

uaddr是用户空间中的地址。

  1. 这样做之后,我可以转换并传递uaddr给我的内核模块函数吗?或者也许我必须以struct pages某种方式使用这些?
  2. 为什么我必须使用向下/向上读取?
  3. 毕竟我必须使用SetPageDirty()page_cache_release()功能?
4

4 回答 4

3
  1. 不,您不能通过 uaddr 直接访问用户空间页面。结构页面被填写以允许内核访问对应于用户空间页面的物理页面。另请注意,它们不太可能是连续的,因此必须小心从 uaddr 开始使用正确的页面索引到数组中。
  2. 您正在更改此进程的页面映射结构,因此需要在设置内核中的页面映射时保护它们。
  3. 当您完成由 get_user_pages() 设置的映射后,您必须通过引用的函数“释放”它们。
于 2011-03-03T03:36:56.780 回答
2

这不是get_user_pages目的(而且不 - 你不能只是转换并传递uaddr给你的内核模块函数)。

如果您不想调用copy_from_user调用函数,则只需将 a 传递void __user *给您的模块函数并让它执行copy_from_user.

于 2009-12-07T23:01:02.870 回答
2

您只能将用户页面用于页面类型活动,例如将 Scatter/Gather DMA 设置到用户空间内存中。您不能使用它直接从内核模式代码访问用户空间。因此,出于这个原因而存在的 copy_to/from 函数。除非您移动大量数据,否则为什么不使用这些功能?

于 2009-12-08T15:33:23.717 回答
0

一旦你得到有效的用户空间地址,使用 get_user_pages 来获取结构页指针。一旦接收到结构页指针,要在内核模式下访问它,您必须使用 kmap 将其映射到内核虚拟地址。希望有帮助

于 2013-06-21T16:11:17.177 回答