Memory-Mapped I/O vs Port-Mapped I/O
Memory-mapped I/O vs port-mapped I/O compared — address spaces, instructions, and caching — with OS interview questions answered.
Expected Interview Answer
Memory-mapped I/O places device registers directly inside the same address space as RAM so the CPU accesses them with ordinary load and store instructions, while port-mapped I/O gives devices a completely separate address space reachable only through dedicated in and out instructions.
With memory-mapped I/O, a range of physical addresses is reserved for device registers rather than RAM, so any instruction that can touch memory — including pointer dereferences and compiler-generated loads — can also touch a device, which means the same addressing modes, caching rules, and instruction set work uniformly for both. With port-mapped I/O, the CPU has a separate, usually smaller, I/O address space and a distinct set of instructions such as x86's IN and OUT, so devices cannot be accidentally touched by a stray memory access, and the memory address space is not consumed by device registers. Memory-mapped I/O is more common in modern systems because it needs no special instructions and works well with virtual memory protection, but it requires care to mark device pages as non-cacheable so reads and writes are not silently reordered or skipped by the cache. Port-mapped I/O keeps the two spaces cleanly separated at the hardware level, which some architectures like x86 still retain for legacy device compatibility even though most modern devices are accessed via memory mapping.
- Memory-mapped I/O reuses ordinary load/store instructions for device access
- Port-mapped I/O keeps device registers isolated from stray memory bugs
- Memory-mapped I/O composes naturally with virtual memory protection
- Understanding both explains x86 legacy IN/OUT alongside modern MMIO devices
AI Mentor Explanation
Memory-mapped I/O is like a scoreboard that shares the same numbered panel positions as the regular match display, so any operator updating the display naturally also updates the scoreboard using the same panel-switching procedure. Port-mapped I/O is like a completely separate hand-cranked scoreboard reachable only through its own dedicated crank handle, so nobody updating the main display can accidentally touch it. The shared-panel approach is simpler to operate but needs a rule that scoreboard panels are never cached in an operator’s memory of yesterday’s numbers, while the separate crank keeps things cleanly isolated but needs its own distinct skill to operate.
Step-by-Step Explanation
Step 1
Address space decision
The architecture decides whether device registers share the memory address space (MMIO) or use a separate I/O space (PMIO).
Step 2
Access instruction
MMIO uses ordinary load/store instructions; PMIO uses dedicated instructions like IN and OUT.
Step 3
Cacheability marking
For MMIO, the page tables mark the device region as non-cacheable so accesses always reach the real device.
Step 4
Driver abstraction
The OS device driver hides which mechanism is used behind read/write register functions the rest of the kernel calls uniformly.
What Interviewer Expects
- Clear contrast between shared vs separate address spaces
- Naming the dedicated IN/OUT instructions for port-mapped I/O
- Why device memory must be marked non-cacheable in MMIO
- Awareness that x86 supports both mechanisms simultaneously
Common Mistakes
- Thinking MMIO and PMIO are interchangeable with no hardware distinction
- Forgetting to mark MMIO regions non-cacheable, causing stale reads
- Believing port-mapped I/O is used by all modern devices
- Confusing MMIO addresses with regular DRAM addresses
Best Answer (HR Friendly)
“Memory-mapped I/O puts device controls at addresses that look just like regular memory, so the same instructions that read and write RAM also talk to devices. Port-mapped I/O instead gives devices their own separate address space that only special instructions can reach, keeping them fully isolated from normal memory access. Most modern hardware favors memory mapping for simplicity, but some CPUs like x86 still support the separate port space for legacy devices.”
Code Example
#include <stdint.h>
/* Memory-mapped I/O: device register is just a pointer into address space */
#define UART_STATUS_REG ((volatile uint32_t *)0x1000A000)
uint32_t read_uart_status_mmio(void) {
return *UART_STATUS_REG; /* ordinary load instruction reaches the device */
}
/* Port-mapped I/O: requires dedicated CPU instructions (x86 example) */
static inline uint8_t inb(uint16_t port) {
uint8_t value;
__asm__ volatile ("inb %1, %0" : "=a"(value) : "Nd"(port));
return value; /* separate I/O address space, not memory */
}Follow-up Questions
- Why must MMIO device pages be marked non-cacheable?
- How does x86 support both MMIO and port-mapped I/O simultaneously?
- What happens if a compiler reorders MMIO reads without volatile?
- How does virtual memory protection interact with MMIO device regions?
MCQ Practice
1. Memory-mapped I/O accesses device registers using?
MMIO places device registers in the normal address space, so regular load/store instructions reach them.
2. Which x86 instructions are used specifically for port-mapped I/O?
x86 reserves the IN and OUT instructions to access its separate port-mapped I/O address space.
3. Why must MMIO regions be marked non-cacheable?
If MMIO were cached, a read could return a stale value instead of the device's current state, breaking correctness.
Flash Cards
What is memory-mapped I/O? — Device registers placed in the same address space as RAM, accessed via ordinary load/store instructions.
What is port-mapped I/O? — Device registers in a separate address space, reachable only via dedicated instructions like IN/OUT.
Why mark MMIO non-cacheable? — To guarantee every access reaches the real device rather than a stale cached value.
Which architecture supports both MMIO and PMIO? — x86, which retains IN/OUT for legacy devices alongside modern MMIO devices.