我正在处理一个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
。在调用 get_user_pages
之前,我们需要为 pages
分配内存(例如使用 kcalloc
)吗?
我的第二个问题是关于 unsigned long start
,在手册页上,它说“起始用户地址”,这是否意味着,如果我在用户空间声明一个指针,如 int *p
,那么我应该将传递给内核空间的“起始用户地址”设为 p
?
我的第三个问题也与 unsigned long start
相关。如果我正确理解了第二个问题,那么我们如何确保该地址恰好从页面开头开始?
以上是三个问题,谢谢。
posix_memalign()
,您可以确保指针对齐,或者在malloc()/mmap() MAP_ANONYMOUS
之后检查它。如果没有对齐,您可以过度分配并自行对齐指针。(保留原始指针以释放内存) - Alexis