Day96 - MMIO Access APIs¶
Objective¶
In this lab, we implement Linux-style MMIO access APIs on top of the ioremap() simulator built in Day95.
The goal is to understand how Linux drivers access hardware registers using readb(), readw(), readl(), writeb(), writew(), and writel() instead of directly dereferencing pointers.
Background¶
After a device's physical registers are mapped into the kernel virtual address space using ioremap(), Linux drivers access registers through dedicated MMIO access APIs.
Typical Linux driver code looks like this:
void __iomem *base;
base = ioremap(PHYS_ADDR, SIZE);
writel(CTRL_ENABLE, base + REG_CTRL);
status = readl(base + REG_STATUS);
These APIs provide a portable interface for accessing device registers across different CPU architectures.
Lab Architecture¶
Physical Device
0x3F200000 - 0x3F2000FF
│
▼
ioremap()
│
▼
Virtual MMIO Address
0x20000000
│
▼
readb()/readw()/readl()
writeb()/writew()/writel()
│
▼
Backing Memory
APIs Implemented¶
| API | Purpose |
|---|---|
readb() |
Read an 8-bit MMIO register |
readw() |
Read a 16-bit MMIO register |
readl() |
Read a 32-bit MMIO register |
writeb() |
Write an 8-bit MMIO register |
writew() |
Write a 16-bit MMIO register |
writel() |
Write a 32-bit MMIO register |
The simulator assumes a Little Endian architecture, matching Raspberry Pi, ARM64, and x86 systems.
Lab 1 — 8-bit MMIO Access¶
Implement and verify:
writeb()readb()
Expected result:
Lab 2 — 16-bit MMIO Access¶
Implement and verify:
writew()readw()
Expected result:
Lab 3 — 32-bit MMIO Access¶
Implement and verify:
writel()readl()
Expected result:
Lab 4 — Little Endian Memory Layout¶
Write the following value:
Verify the bytes stored in memory:
Expected result:
Lab 5 — Register Layout with Offsets¶
Implement register accesses using register offsets.
Example:
writel(1, base + REG_CTRL_OFFSET);
status = readl(base + REG_STATUS_OFFSET);
data = readl(base + REG_DATA_OFFSET);
Expected result:
Lab 6 — Boundary Validation¶
Verify that every MMIO access stays within the mapped region.
Test:
- last valid 32-bit access
- invalid access beyond the mapping boundary
Expected result:
Lab 7 — Multiple MMIO Mappings¶
Create two independent MMIO mappings.
Verify:
- different physical addresses
- different virtual addresses
- independent register values
Expected result:
Summary¶
In this lab, we implemented Linux-style MMIO access APIs and verified:
- 8-bit, 16-bit, and 32-bit register access
- Little Endian register layout
- Register access using offsets
- Mapping boundary validation
- Multiple independent MMIO mappings
The completed MMIO workflow is now:
Physical Address
│
▼
ioremap()
│
▼
Virtual MMIO Address
│
▼
readb()/readw()/readl()
writeb()/writew()/writel()
This is the same programming model used by Linux platform drivers to access hardware registers.