I wanted to ask what are the benefits of mapping a device file using mmap. There is a driver which implements file operations API for that device file.

I'm asking since device files are not stored on hard storage so mmap won't save us I/O. In addition whether we write into that device file directly (after mapping it) or use the write system call we still use kernel code and system calls since the driver is implemented in kernel space.


1 Answer 1


Formally speaking you do not "mmap a device file" (some /dev/xyz special file) you mmap regions of device's memory into user-space.

If some device's control registers are mmaped, (actually the case for most PCI peripherals) this will actually enable the program to get the work done without repeatedly having to call ioctl. (indeed saving time, time in kernel space & IO)

If you get to transfer a lot of data to and from the device (a typical example would be with video memory); mapping the device's memory to user space will actually improve the throughput, since the program can get rid of the lseek/write/read system calls. it would have had to resort to.

Of course, even when mmaped, the program can still access the device via the ioctl/read/write system calls which will certainly cause I/O occurrences, time spent in kernel space, loosing all the benefits of the mmapping meant to get rid of them.

Elaborating following comments :

virt_addr = map_base + target; each time I'll write into virt_addr , behind the scenes, the device driver will invoke its read function?

From the point device's memory is mmap-ed, the device driver can be completely bypassed. No call to whatever device driver function is needed, even behind the scene. Updating virt_addr content won't be translated into whatever system call.
If something is working behind the scene it will at most be the IO-MMU.

  • 2 questions please regarding your answer: 1. In the following code: fd = open(CHAR_DEV_FILE , O_RDWR | O_SYNC) /* map one page /map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); / calculate the virtual address to be accessed */ virt_addr = map_base + target; each time I'll write into virt_addr , behind the scenes, the device driver will invoke its read function? 2. If I want to write and read big files as you said, how I know which "target" (offset) I have to use? does the driver has to contain driver code which executed once the char_dev has been mmaped
    – hutcruchi
    Oct 31, 2022 at 10:57
  • @hutcruchi : I updated my answer regarding your first question. For what concerns the second, you write willing to "read/write big files" Does this explicitly mean that the device you are interested in is some block device of some particular filesystem ?
    – MC68020
    Oct 31, 2022 at 11:22
  • the device is Xilinx PCIe DMA with linux but the lack of knowledge is general =). I saw the driver has a .mmap file operation. so I learn that: 1. I can use the driver's write/read/ioctl file operations. 2. I can use the driver's mmap file operation once and from that point to work directly with virtual memory pointers. my followup question is: after mmap the device file I get a pointer. where I can see to which address in the available FPGA address space this pointer is "pointing"? this logic not appears in the driver's mmap file operation implementation.
    – hutcruchi
    Oct 31, 2022 at 11:34
  • @hutcruchi : Ha! mmap & dma… could be a topic per se. You probably could be interested in reading oreilly.com/library/view/linux-device-drivers/0596000081/… first.
    – MC68020
    Oct 31, 2022 at 12:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .