2
votes

I'm working on a driver-like code for a PCI device which. The communication is done through a buffer, i.e. I write to a buffer and device grabs data from it. Device writes to a buffer and I grad data from it. Here is where the problem occurs. In order for a device to write to this buffer it needs to have its physical address (not virtual one). My boss told me it is possible to do it if I write a kernel module and allocate memory using kmalloc.

Here are my questions. How do I get access to this buffer from a user space, i.e. how do I pass a pointer to this buffer from a kernel space to a user space? Since all addresses in user space are virtual addresses, how do I convert a physical pointer to this buffer to a virtual one? As far as I understand I need to use ioctl but I don't how.

Any help is appreciated.

2
If I was to do this I would probably take a look at the DRM in the graphics drivers - doron
Implement mmap in your driver to do that. Read Linux Device Drivers for more details. - kaylum
@kaylum That's the book I've been reading for the past week. I did look at the relevant chapters for my case and I don't think mmap is the right approach. The trick is that I'm the one who has to allocate a buffer, however in order for the device to write to it, it needs a physical address of the buffer. - flashburn
@doron Can you elaborate more, I'm not sure I know what you are talking about. - flashburn
But your actual question is "how do I pass a pointer to this buffer from a kernel space to a user space". That is exactly what mmap will achieve. - kaylum

2 Answers

1
votes

If this is a PCI device then it already has a physical address than you need to map. Your device has a class and a subclass id. Spin through all of your pci devices until you get a match on your class and subclass id then pull the bus address from that.

You then map the physical address using mmap

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

I hope this helps.

0
votes

Maybe you could use Netlink Socket API. This link could be of help to you How to use netlink socket to communicate with a kernel module?