Read a memory-mapped device
Write a Linux userspace MMIO driver for a temperature sensor implemented by the emulator.
Jump to code and terminal ↓Real reads, fictional hardware
The Acme temperature sensor is a custom device inside the RISC-V emulator. Its registers occupy physical address 0x40000000. A CPU load from that address reaches the device implementation, rather than ordinary RAM. The browser controls temperature and connection state; the access log records the CPU's MMIO operations.
Map the registers from Linux
The scaffold opens /dev/mem and maps one device page. Fill in read32 and write32 using the mapped address plus the register offset. Each access must be 32 bits and volatile so the compiler preserves the hardware access. Try heating or disconnecting the sensor, then run the program again.
0x00 DEVICE_ID 0xAC1E0001 (read only) 0x04 TEMPERATURE signed degrees Celsius (read only) 0x08 CONTROL bit 0: enabled (read/write) 0x0C STATUS bit 0: enabled; bit 1: disconnected
Where this fits in driver development
This first exercise is a privileged Linux userspace driver, not a loadable kernel module. It makes the hardware boundary observable without shipping kernel headers and a module toolchain in the first download. A later lesson will use a platform driver, ioremap, readl/writel, and an interrupt handler.
Your goal
Implement 32-bit register reads and writes, identify the sensor, and toggle its enable bit without losing other control bits.
What the tests observe
- DEVICE_ID is 0xAC1E0001
- CONTROL writes change STATUS
- Temperature follows the browser control
- The emulator records each MMIO access
Need a nudge?
Hint 1
base is a byte pointer, so base + offset selects the register's byte address. Convert that address to a pointer to a volatile uint32_t.
Hint 2
Reading through the pointer performs a CPU load; assigning through it performs a CPU store. Keep volatile on the pointed-to type.
Hint 3
A read has the form *(volatile uint32_t *)(base + offset). A write assigns value through the same kind of pointer.
What happens inside Linux
Linux maps the physical device page into the process. Loads and stores pass through the emulated CPU into the Acme device's register handlers. The device updates STATUS in response to CONTROL writes; the test checks that response, not just the written value. Userspace access has no kernel driver binding, interrupt handler, or safe multi-client ownership yet.
Optional account sync. Exercises work without an account.