"get_user_pages" 是如何工作的(针对 linux 驱动程序)
How does "get_user_pages" work (For linux driver)
正在研究 Linux PCI 驱动程序,现在我正在尝试使用 scatter/gather 为 DMA 编写代码。
目前,我了解到要直接从用户 space 访问 DMA 数据,我们需要将用户 space 页面固定到内核 space。
为此,我们有 get_user_pages
,它的完整定义如下:
int get_user_pages(struct task_struct * tsk,
struct mm_struct * mm,
unsigned long start,
int nr_pages,
int write,
int force,
struct page ** pages,
struct vm_area_struct ** vmas);
我的第一个问题是关于 struct page ** pages
。在调用 get_user_pages
之前,我们是否需要为 pages
分配内存(例如使用 kcalloc
)?
我的第二个问题是关于 unsigned long start
,在手册页上,它说 "starting user address",这是否意味着,如果我在用户 space 中声明一个指针,例如 int *p
,我应该传递给内核 space 的 "starting user address" 是 p
?
我的第三个问题也是关于unsigned long start
,如果我在第二个问题中理解正确,那么我们如何确保这个地址恰好在页面的开头?
所以三个问题,感谢提前。
My first question is about the struct page ** pages. Here do we need to allocate memory(using kcalloc for ex.) for the pages before calling the get_user_pages?
可以,但不是必须的,一个数组就足够了(其大小取决于nr_pages
)
如果要固定4页,struct page *pages[4];
就够了。
My second question is about the unsigned long start, on the man page, it says "starting user address", does it mean that, if I declare a pointer like int *p, the "starting user address" I should pass to kernel space is p?
此参数应指向您的用户进程拥有的内存(如 malloc
之后)。
My third question is also about the unsigned long start, if I understand correctly in the second question, then how can we make sure that this address begins exactly at the beginning of a page?
我想你可以用 getpagesize
函数来完成。
我认为这篇博文:"get_user_pages example" 可能对您有所帮助。
正在研究 Linux PCI 驱动程序,现在我正在尝试使用 scatter/gather 为 DMA 编写代码。
目前,我了解到要直接从用户 space 访问 DMA 数据,我们需要将用户 space 页面固定到内核 space。
为此,我们有 get_user_pages
,它的完整定义如下:
int get_user_pages(struct task_struct * tsk,
struct mm_struct * mm,
unsigned long start,
int nr_pages,
int write,
int force,
struct page ** pages,
struct vm_area_struct ** vmas);
我的第一个问题是关于 struct page ** pages
。在调用 get_user_pages
之前,我们是否需要为 pages
分配内存(例如使用 kcalloc
)?
我的第二个问题是关于 unsigned long start
,在手册页上,它说 "starting user address",这是否意味着,如果我在用户 space 中声明一个指针,例如 int *p
,我应该传递给内核 space 的 "starting user address" 是 p
?
我的第三个问题也是关于unsigned long start
,如果我在第二个问题中理解正确,那么我们如何确保这个地址恰好在页面的开头?
所以三个问题,感谢提前。
My first question is about the struct page ** pages. Here do we need to allocate memory(using kcalloc for ex.) for the pages before calling the get_user_pages?
可以,但不是必须的,一个数组就足够了(其大小取决于nr_pages
)
如果要固定4页,struct page *pages[4];
就够了。
My second question is about the unsigned long start, on the man page, it says "starting user address", does it mean that, if I declare a pointer like int *p, the "starting user address" I should pass to kernel space is p?
此参数应指向您的用户进程拥有的内存(如 malloc
之后)。
My third question is also about the unsigned long start, if I understand correctly in the second question, then how can we make sure that this address begins exactly at the beginning of a page?
我想你可以用 getpagesize
函数来完成。
我认为这篇博文:"get_user_pages example" 可能对您有所帮助。