Linux drivers · Course contents
Machine not started
25 min·Intermediate

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.

C/work/sensor.cLoading local work…
Restoring your workspace…
⌘ / Ctrl ↵
TerminalRISC-V 64 · root · /work

Your Linux machine is ready to start.

Boot a disposable environment in this browser. You’ll get a real root shell, with no remote server or account required.

Acme temperature sensor

Emulated MMIO hardware
42°C
Address
0x40000000
Connection
connected
Control
unobserved
Accesses shown
0

Start Linux and run your driver. Reads and writes to the device will appear here as they happen.