在Linux PCI驱动程序上工作,现在我正尝试使用分散/聚集为DMA编写代码。
到目前为止,我已经了解到,要直接从用户空间访问DMA数据,我们需要将用户空间页面固定到内核空间。
为此,我们有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
。在这里,我们需要为分配内存(kcalloc
用于ex),pages
然后再调用get_user_pages
吗?
我的第二个问题是关于unsigned long start
,在手册页上说“起始用户地址”,这是否意味着,如果我在用户空间中声明一个指针,例如int *p
,我应该传递给内核空间的“起始用户地址”是p
?
我的第三个问题也与有关unsigned long start
,如果我对第二个问题的理解正确,那么我们如何确保此地址恰好在页面的开头?
所以这三个问题,谢谢你的推进。
我的第一个问题是关于struct页面**页面。在调用get_user_pages之前,我们是否需要在页面上分配内存(例如,使用kcalloc)?
您可以,但不是强制性的,数组足够了(其大小取决于nr_pages
)
如果要固定4页,struct page *pages[4];
就足够了。
我的第二个问题是关于无符号长启动的问题,在手册页上它显示“ starting user address”,这是否意味着,如果我声明了一个类似int * p的指针,则应该将“ starting user address”传递给内核空间是p吗?
此参数应指向用户进程拥有的内存(如malloc
)。
我的第三个问题也是关于无符号的长距离启动,如果我在第二个问题中理解正确,那么我们如何确保该地址恰好在页面的开头?
我想你可以用getpagesize
功能做到这一点。
我认为此博客文章:“ get_user_pages示例”可能会对您有所帮助。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句