如何将指针指向物理内存从内核空间传递到用户空间并将其映射到虚拟空间

问题描述:

我正在研究PCI设备的驱动程序代码。通信是通过缓冲区完成的,即我写入缓冲区,设备从中获取数据。设备写入缓冲区,并从中读取数据。这是问题发生的地方。为了让设备写入这个缓冲区,它需要有它的物理地址(而不是虚拟地址)。我的老板告诉我,如果我编写内核模块并使用kmalloc分配内存,则可以这样做。如何将指针指向物理内存从内核空间传递到用户空间并将其映射到虚拟空间

这是我的问题。 如何从用户空间访问此缓冲区,即如何将指针从内核空间传递到用户空间?由于用户空间中的所有地址都是虚拟地址,因此如何将物理指针转换为虚拟地址?据我所知,我需要使用ioctl,但我不知道如何。

任何帮助表示赞赏。

+0

如果我要这样做,我可能会看看图形驱动程序中的DRM – doron

+4

在您的驱动程序中实现'mmap'来执行此操作。阅读[Linux设备驱动程序](http://www.xml.com/ldd/chapter/book/ch13.html)了解更多详情。 – kaylum

+0

@kaylum这是我过去一周一直在阅读的书。我的确看过我的案例的相关章节,我不认为'mmap'是正确的方法。诀窍是我必须分配一个缓冲区,但是为了让设备写入缓冲区,它需要缓冲区的物理地址。 – flashburn

也许你可以使用Netlink套接字API。这个链接可能对你有帮助How to use netlink socket to communicate with a kernel module?

+0

感谢您的回复,但这不完全是我正在寻找的。正如我所说的,通信是通过缓冲区完成的,而用户负责缓冲区分配。但是,设备需要为此缓冲区提供物理地址,以便从/向其读取/写入数据。 – flashburn

如果这是一个PCI设备,那么它已经有一个物理地址比你需要映射。您的设备有一个类和一个子类ID。旋转你所有的pci设备,直到你在你的类和子类ID上找到一个匹配,然后从那里拉出总线地址。

然后,您可以使用mmap

C++ app to talk to an FPGA over PCI in userland using mmap

我希望这可以帮助映射的物理地址。