ioremap()¶
Overview¶
Memory-Mapped I/O (MMIO) allows hardware peripherals to expose registers through physical memory addresses.
Unlike normal RAM, these physical addresses correspond to hardware devices rather than system memory.
Linux drivers cannot directly access MMIO physical addresses. Instead, they must create a kernel virtual mapping using ioremap().
After mapping, drivers access device registers through the returned virtual address using APIs such as readl() and writel().
Why ioremap()?¶
Modern operating systems use virtual memory.
Kernel code normally operates on virtual addresses, while hardware peripherals expose fixed physical addresses.
For example:
Instead of directly accessing this physical address, Linux performs:
The returned virtual address is then used throughout the driver.
Linux MMIO Architecture¶
In Linux, ioremap() establishes a page-table mapping between a virtual address and a physical MMIO region.
Whenever the driver accesses the mapped address, the CPU MMU performs address translation automatically.
The driver never performs this translation itself.
Simulator Architecture¶
The simulator cannot modify kernel page tables.
Instead, it implements a simplified MMIO mapping layer entirely in userspace.
+----------------------+
| io_region |
+----------------------+
| Physical Address |
| Size |
| Backing Storage |
+----------+-----------+
|
|
+----------v-----------+
| io_mapping |
+----------------------+
| Virtual Address |
| Physical Address |
| Size |
+----------+-----------+
|
▼
io_mapping_translate()
|
▼
Backing Storage Pointer
Unlike Linux, the simulator introduces backing storage.
This storage is allocated from heap memory and simulates hardware registers.
MMIO Region¶
A region represents a physical MMIO device.
Each registered region owns:
- Physical base address
- Region size
- Simulated backing storage
Multiple virtual mappings may reference the same region.
Virtual Mapping¶
Drivers create virtual mappings using ioremap().
The simulator allocates virtual addresses independently of the backing storage.
For example:
Mappings are allocated in page-sized increments, similar to Linux.
Address Translation¶
The simulated virtual address cannot be dereferenced directly.
Instead:
Virtual Address
│
▼
Find Mapping
│
▼
Calculate Mapping Offset
│
▼
Calculate Region Offset
│
▼
Backing Storage
The translation computes:
This replaces the work normally performed by the MMU.
Mapping Lifecycle¶
The ownership model follows the Linux driver model.
A region cannot be removed while active mappings still exist.
Linux vs Simulator¶
| Linux | Simulator |
|---|---|
| Hardware registers | Backing storage |
| Physical address | Physical address |
| Page table | Mapping list |
| MMU | io_mapping_translate() |
| Kernel virtual address | Simulated virtual address |
readl() directly accesses MMIO |
readl() translates to backing storage |
Key Points¶
- MMIO devices are accessed through memory addresses rather than I/O ports.
ioremap()converts a physical MMIO address into a kernel virtual address.- Linux relies on the MMU to perform address translation automatically.
- The simulator replaces the MMU with
io_mapping_translate(). - Backing storage exists only in the simulator to emulate hardware registers.
- Multiple virtual mappings may reference the same physical MMIO region.