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

Handle and acknowledge an interrupt

Receive a real level-triggered PLIC interrupt and clear the device source before returning.

Jump to code and terminal ↓

The source stays asserted

Writing SAMPLE generates a hardware event. The emulator asserts PLIC source 16, Linux claims it, and the supplied IRQ wrapper invokes student_interrupt. pending bit 0 means a sample; bit 1 means a completed DMA request. Acknowledgment is a write-one-to-clear register, not a read.

Complete the handler

For a sample, update last_temperature and increment state->count. Write the pending mask to LAB_IRQ_ACK before returning. The wrapper completes the PLIC claim, but only the device acknowledgment clears the source. /proc/interrupts shows real Linux IRQ accounting.

Diagnose a storm

A missing acknowledgment repeatedly invokes the handler. After 128 unacknowledged calls, the harness disables this peripheral's IRQ-enable bit so the disposable browser machine remains recoverable. The storm sysfs attribute records that condition, and the test fails. This guard is part of the scaffold, not a substitute for correct device acknowledgment.

Your goal

Count each sample interrupt once and acknowledge every pending bit so the device deasserts its IRQ.

What the tests observe

  • Three sample requests yield three handled interrupts
  • IRQ_STATUS becomes zero after acknowledgment
  • No storm guard is triggered
  • The driver is present in /proc/interrupts

Need a nudge?

Hint 1

Read LAB_TEMPERATURE only when pending & 1 is true, and count that event once.

Hint 2

Writing zero to IRQ_ACK clears no bits. Write the mask you handled.

Hint 3

Set state->last_temperature from read32, increment state->count, then call write32 with LAB_IRQ_ACK and pending.

What happens inside Linux

A device raises a supervisor external interrupt through the PLIC. Linux dispatches the registered IRQ action, your callback handles the cause, and a W1C MMIO write deasserts the device line. The PLIC completion and peripheral acknowledgment are separate operations.

Optional account sync. Exercises work without an account.

Reference headers and helper functions

Read-only lesson support. Your editable implementation is below.

lab_driver.h

/* SPDX-License-Identifier: GPL-2.0-only
 * Narrow module callback ABI. Implementations execute in Linux kernel context.
 * The supplied platform harness owns registration, mappings, IRQ registration,
 * coherent allocation, sysfs lifetime, and module cleanup.
 */
#ifndef LAB_DRIVER_H
#define LAB_DRIVER_H
typedef unsigned int lab_u32;
typedef unsigned long lab_u64;
#define LAB_ID 0x00
#define LAB_TEMPERATURE 0x04
#define LAB_CONTROL 0x08
#define LAB_STATUS 0x0c
#define LAB_IRQ_STATUS 0x10
#define LAB_IRQ_ACK 0x14
#define LAB_SAMPLE 0x18
#define LAB_DMA_LO 0x20
#define LAB_DMA_HI 0x24
#define LAB_DMA_START 0x28
#define LAB_DMA_STATUS 0x2c
#define LAB_DEVICE_OWNS 1U
#define LAB_DMA_DONE 2U
struct lab_dma_descriptor {
    lab_u64 address;
    lab_u32 length, flags, completed, reserved;
};
struct lab_api {
    void *context;
    lab_u32 (*read32)(void *, unsigned int);
    void (*write32)(void *, unsigned int, lab_u32);
    void (*write_barrier)(void);
    void (*read_barrier)(void);
};
struct lab_irq_state { lab_u32 count, last_temperature; };
int student_probe(const struct lab_api *);
int student_temperature(const struct lab_api *);
void student_interrupt(const struct lab_api *, lab_u32, struct lab_irq_state *);
int student_dma_submit(const struct lab_api *, struct lab_dma_descriptor *, lab_u64, lab_u64, lab_u32);
int student_dma_complete(const struct lab_api *, struct lab_dma_descriptor *);
#endif
C/work/driver.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

Linux kernel driver
42°C
Address
0x40000000
Connection
connected
Control
unobserved
Accesses shown
0
IRQ enable
unobserved
Hardware events shown
0

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

Interrupts and DMA

The emulator records hardware interrupts, acknowledgments, and DMA transfers here. Load your driver and request a sample to observe the device.