Skip to main content

System Driver Types (Linux)

User Space Driver

When full access to a device's resources is not required, a User Space Driver (USD) can utilize system interfaces for limited access to the device's memory space and handling interrupts1.

If the driver needs to access privileged functions, such as ioperm() system calls to access x86 I/O ports, root-privileges are necessary.

User Space Drivers offer a restricted alternative to Kernel Space Drivers. Their key advantage lies in improved system stability: If a bug slips into the User Space Driver, only the corresponding process is at risk of crashing, not the whole system.

Kernel Space Driver

Kernel Space Drivers are embedded into the kernel space and provide full access to a device's memory and I/O ports. They can be statically linked into the kernel, requiring a full kernel compilation whenever the implementation of the driver changes. Errors in the driver itself will most likely negatively affect the stability of the whole system.

As an alternative, Loadable Kernel Modules (LKM) allow drivers to be dynamically inserted into a running kernel without recompilation2. System directives such as insmod can be used for loading these modules.

LKMs help reduce kernel size and compile times, accelerating development cycles (load \rightarrow test \rightarrow unload). However, they might introduce a slight performance overhead due to the additional abstraction layer between the module and the kernel.

insmod / rmmod

  • insmod is used for loading an LKM into the kernel.

  • rmmod is used for unloading an LKM3.

The following excerpt from a bash script demonstrates the usage of insmod / rmmod: The call to rmmod removes the specific module if it was already loaded4, insmod loads it accordingly.

#! /bin/bash

sudo rmmod ${MODULE} 2>/dev/null

# loads the module
sudo insmod ${MODULE}.ko || { echo "Error loading ${MODULE}.ko"; exit 1; }

init_module / cleanup_module

Additionally, there exist two functions in the Linux-Kernel library <linux/module.h> that can be used as callbacks when the LKM has been loaded / unloaded for further bootstrapping module functionality, requesting system resources and freeing them, respectively:

  • init_module: Called when the module is initialized (insmod)

  • cleanup_module: Called when the module is unloaded (rmmod)

The following listing5 shows the usage of init_module() and cleanup_module(). Take note that

  • device_major specifies the major device number6 associated with the device implemented by the module. We set this to 0 and expect the kernel to dynamically allocate a device identifier.
  • register_chrdev / unregister_chrdev takes care of (un)registering the module with the kernel: register_chrdev provides information to the kernel which file-operations are mapped to which functions in the specific module. unregister_chrdev de-registers this information accordingly.
#include <linux/module.h>
#include <linux/fs.h>
...

#define MODULE_NAME "myModule"

static int device_major = 0;

struct file_operations module_fops = {
.owner = THIS_MODULE,
// ...
};


int init_module(void) {

printk(KERN_INFO "%s init start:\n", MODULE_NAME);
int result = register_chrdev(device_major, MODULE_NAME, &module_fops);

if (result < 0) {
printk(KERN_ERR " Failed to register %s: Error %d\n", MODULE_NAME, result);
return result;
}

if (device_major == 0) {
device_major = result;
}
...

return 0;
}


void cleanup_module(void) {
printk(KERN_INFO "%s cleanup start:\n", MODULE_NAME);
unregister_chrdev(device_major, MODULE_NAME);

...

}

Footnotes

  1. https://www.kernel.org/doc/html/latest/driver-api/uio-howto.html, retrieved 01.05.2025

  2. https://en.wikipedia.org/wiki/Loadable_kernel_module, retrieved 01.05.2025

  3. The man-pages specifically point to modprobe which takes care of unloading interdependent modules

  4. while ignoring possible error messages like rmmod: ERROR: Module is not currently loaded

  5. static int device_major takes care of limiting the scope of device_major to the compilation unit ([📖KR88, p. 83])

  6. 'Device nodes and major/minor numbers': https://www.ibm.com/docs/en/linux-on-systems?topic=hdaa-device-nodes-numbers, retrieved 02.05.2025