Chapter 9. Device Drivers

Table of Contents

9.1. Interrupt Notifications
9.2. Accessing Memory and I/O Space
9.3. Disabling Preemption

Since HelenOS is a microkernel, a framework for supporting userspace device drivers has been implemented. A typical userspace task acting as a device driver might need to:

9.1. Interrupt Notifications

Userspace tasks that are in hold of the CAP_IRQ_REG capability can register themselves via the ipc_register_irq() to be notified about occurrences of a given interrupt. The registration call takes two arguments. The first argument is the IRQ number and the second is the pointer to special pseudocode that instructs the kernel interrupt handler how to process the IRQ. Currently the pseudocode language supports reading and writing physical memory, reading from and writing to I/O space and actions related to running HelenOS in virtual environments.

When the interrupt comes after its handler has been registered by a userspace task, the kernel interrupt handler interprets the pseudocode program and sends an IPC notification to the respective task. The userspace task can get certain information about the interrupt (e.g. what key was pressed) by issuing memory or I/O space reads in the pseudocode program. The read values are wrapped into the IPC notification sent to the task. The write operations are also very essential because some interrupts are level-sensitive and need to be processed in the kernel interrupt routine. In many situations, the interrupt is considered serviced only when the interrupt handler performs certain reads or writes of memory or I/O space.

9.2. Accessing Memory and I/O Space

When a task has the CAP_MEM_MANAGER capability, it can use the SYS_MAP_PHYSMEM to map regions of physical memory to its address space. When successful, the syscall creates an address space area for the physical memory region. The address space area can be further shared by other tasks. Similarily, when a task has the CAP_IOSPACE_MANAGER capability, it is entitled to request access to the I/O space by using the SYS_IOSPACE_ENABLE. However, this syscall is relevant only on architectures that have separate I/O space (e.g. amd64 and ia32).

9.3. Disabling Preemption

It might be desirable for a device driver to temporarily disable preemption. Tasks that can do this are required to have the CAP_PREEMPT_CONTROL capability. Preemption could be theoretically disabled by disabling interrupts on the current processor, but disabling preemption is more lightweight as interrupt processing remains enabled.