Linux – What’s the difference between ioremap and file operation mmap

iolinuxlinux-kernelmemorypci

I'm currently working on a PCI device driver for Ubuntu. I have some example code about PCI driver, but I have difficult on understanding the ioremap and file_operation.mmap.

The description of file operation mmap:

Memory mapping is one of the most interesting features of modern Unix systems. As far as drivers are concerned, memory mapping can be implemented to provide user programs with direct access to device memory. Mapping a device means associating a range of user-space addresses to device memory. Whenever the program reads or writes in the assigned address range, it is actually accessing the device.

The description of ioremap:

On many systems, I/O memory is not directly accessible in this way at all. So a mapping must be set up first. This is the role of the ioremap function.The function is designed specifically to assign virtual addresses to I/O memory regions.

The above description all come from "makelinux". But still I'm not sure if I correctly understand the difference between the two functions. For now, I understand it the way like this: The fops.mmap(file operation mmap) associates a range of user-space addresses to device memory. Which means for a pci device, we do real address map for the device's BAR with fops.mmap.
And with ioremap, we do virtual address map for these "real addresses" got from fops.mmap.

Could someone tell me if I was wrong? Thx~

PS. I posted this also in Ubuntu community, hope I didn't break any rules.

Best Answer

I suggest you look into the LDD3 book, it is free. It does explain ioremap in chapter 9, page 249. Also look into APIU 3rd edition, chapter 14.8, page 525. Let me summarize, best to my abilities:

ioremap is a kernel function that allows to access hardware through a mechanism called I/O mapped memory. There are certain addresses in memory that are intercepted by motherboard between CPU and RAM and redirected to other hardware, like disks or keyboard. Not sure if you can use the usual addressing through pointers or some other kernel functions.

I/O memory is simply a region of RAM-like locations that the device makes available to the processor over the bus. This memory can be used for a number of purposes, such as holding video data or Ethernet packets, as well as implementing device registers that behave just like I/O ports (i.e., they have side effects associated with reading and writing them).

mmap is a syscall available in user space that maps a process memory region to content of a file, instead of RAM. When you access that mapped region of memory, through usual pointer dereference, kernel translates it to a file operation. Essentially writing to memory becomes writing into a file. It is just a more fancy way of calling write().

Memory-mapped I/O lets us map a file on disk into a buffer in memory so that, when we fetch bytes from the buffer, the corresponding bytes of the file are read. Similarly, when we store data in the buffer, the corresponding bytes are automatically written to the file. This lets us perform I/O without using read or write.

(sidenote) I think first is called "IO mapped memory" and second is called "memory mapped IO". No wonder you are confused.

Related Question