1

In Operating System Concepts, memory mapped files and memory mapped I/O are two different things. See below about memory mapped I/O.

To use memory mapped files, we have mmap().

To use memory mapped I/O, what functions can we use? Is memory mapped I/O only used internally by OS, not exposed to and used by programmers on top of Linux?

Thanks.

In the case of I/O, as mentioned in Section 1.2.1, each I/O controller includes registers to hold commands and the data being transferred. Usually, special I/O instructions allow data transfers between these registers and system memory. To allow more convenient access to I/O devices, many computer architectures provide memory-mapped I/O. In this case, ranges of memory addresses are set aside and are mapped to the device registers. Reads and writes to these memory addresses cause the data to be transferred to and from the device registers. This method is appropriate for devices that have fast response times, such as video controllers. In the IBM PC, each location on the screen is mapped to a memory location. Displaying text on the screen is almost as easy as writing the text into the appropriate memory-mapped locations.

...

How can the processor give commands and data to a controller to accomplish an I/O transfer? The short answer is that the controller has one or more registers for data and control signals. The processor communicates with the controller by reading and writing bit patterns in these registers. One way in which this communication can occur is through the use of special I/O instructions that specify the transfer of a byte or word to an I/O port address. The I/O instruction triggers bus lines to select the proper device and to move bits into or out of a device register. Alternatively, the device controller can support memory-mapped I/O. In this case, the device-control registers are mapped into the address space of the processor. The CPU executes I/O requests using the standard data-transfer instructions to read and write the device-control registers at their mapped locations in physical memory.

  • Isn't the dev filesystem what you're supposed to use to connect with I/O controllers of all sorts? – Shadur Oct 17 '18 at 6:49
8

On Linux, MMIO is possible from user-space using mmap on /dev/mem. For example, the X server does

fd = open("/dev/mem", O_RDWR);
if (ioBase == NULL) {
    ioBase = (volatile unsigned char *) mmap(0, 0x20000,
                                             PROT_READ | PROT_WRITE,
                                             MAP_SHARED, fd, ioBase_phys);
}
close(fd);

in some cases. This is going out of fashion though and the kernel strictly controls what can be done using this type of access: accessing /dev/mem requires CAP_SYS_RAWIO, and distribution kernels nowadays tend to be built with STRICT_DEVMEM and IO_STRICT_DEVMEM which restrict access via /dev/mem to a few ranges in memory, either required for DOSEMU or X, or mapped to devices and otherwise unused (i.e. providing MMIO for a device which isn’t handled by a driver).

  • By the definition quoted in the question, the framebuffer counts as memory-mapped I/O space. So there's another mmap() possibility. – JdeBP Oct 16 '18 at 14:16
  • Thanks. Does MMIO map controller's registers and memory to virtual memory addresses or physical memory addresses? Does MMIO involve virtual memory, or just physical memory? – Tim Oct 17 '18 at 0:28
  • The advantage of memory mapped file over standard IO system calls is to avoid copying from kernel cache/buffer to userspace buffer. Is the advantage of MMIO over port I/O also similar? – Tim Oct 17 '18 at 0:38
  • MMIO, viewed from the CPU’s perspective, is based on physical addresses, which can be mapped to virtual (linear) addresses if necessary. Viewed from the device’s perspective, it uses physical addresses, unless an IOMMU is involved. /dev/mem uses physical addresses only. – Stephen Kitt Oct 17 '18 at 12:22
  • For MMIO you definitely want to avoid caches ;-). However the main advantage of MMIO over port I/O is that the number of available ports is small, and that accessing other devices’ memory using port I/O would be prohibitively slow (think of multi-gigabyte GPUs). – Stephen Kitt Oct 17 '18 at 12:24
4

Memory mapped I/O is done by mmap()ing a region of a file and then using the mapped data.

If you use a modern OS, the OS does most I/O mmapp'ing internally:

  • map parts of the file into a transient kernel area

  • copyout() the mapped data to the user address space. This causes the file content to be faulted into the transient memory area of the kernel.

  • unmap the region

BTW: if you are referring to accessing hardware from user space, this is usually done e.g. by the X Server that mmap()s the hardware from the graphics board and accesses it from user space.

The device registers are accessible as memory addresses in that case and you just write code that looks as if you were inside the kernel. In other words: you do not use read() or write(), but just dereference pointers that point to the addresses of the hardware registers.

  • I would not use the term memory mapped IO in relation to UNIX while talking about hardware access. If you however like to access hardware from user space, you need special privileges to be allowed to mmap() the addresses that are used by interface hardware. Then you can use the hardware from user space as if you were in the kernel. – schily Oct 16 '18 at 13:41
  • @StephenKitt In MMIO, are the device controllers' registers and memory exposed as device files, so that system calls including read(), write(), and mmap() can apply to the device files? – Tim Oct 16 '18 at 13:44
  • I added an explanation on how the device registers are accessed in such a case. – schily Oct 16 '18 at 15:16
  • Obviously the quoted text refers to memory mapped I/O in the hardware sense. Instead of the "special I/O instructions", of which the 8086 IN and OUT instructions are an example, the hardware is designed so that the I/O device registers appear in the memory address space, and normal memory access instructions like MOV are used. This is done in the in-kernel device driver, and no files are involved. The Operating System Concepts book is not a Unix-specific book, but intends to "provide a solid theoretical foundation for understanding operating systems." – Johan Myréen Oct 16 '18 at 16:38
  • libdrm would also be worth mentioning - it's what the Mesa OpenGL drivers use to map video memory into a user process (and is probably a wrapper around a kernel interface). Then other drivers could also provide kernel interfaces where appropriate, such as the RDMA interface wrapped in the ibverbs and rdmacm libraries (though that's probably a bit different - there, a user process registers a region of its virtual memory locked to be resident for the RDMA card to read/write directly). – Daniel Schepler Oct 16 '18 at 18:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.