Linux – Is memory mapped I/O only used internally by OS, not exposed to and used by programmers on top of Linux

iolinuxmemory-mapped-file

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.

Best Answer

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).

Related Question