Hardware management

This document describes how the kernel interacts with hardware.

Hardware detection

Devices are detected during the boot process and then periodically after startup. This allows to hotplug some additional devices afterwards.

As all devices do not use the same connection protocols, the detection process depends on the connection:

  • PCI-Express devices are detected through their Configuration Space
  • IDE/SATA devices are detected through the IDE/SATA controller
  • USB devices are enumerated through the USB protocol stack
  • Motherboard-connected devices are enumerated through the BIOS/UEFI (e.g. CPU and case fans)

Some devices may not be detected through these though, such as some legacy ISA devices, which will be detected through a set of methods like ACPI enumeration or simply checking UART serial ports.

Connection interface identifier

The connection interface identifier (CII) is a 4-byte number describing what a device is connected to:

  • Connection type (1 byte):
    • 0x01: PCI-Express
    • 0x02: IDE
    • 0x03: SATA
    • 0x04: M.2
    • 0x05: USB
    • 0x06: RGB
    • 0x07: Fans
  • Bus number (1 byte)
  • Port number (2 bytes)

For instance, the seventh USB port on the second bus will have the 0x05010006 CII.

Connection-specific device descriptor

All hardware devices expose a normalized identifier whose format depends on the connection type (PCI-Express, SATA, ...). This identifier is called the connection-specific device descriptor (CSDD).

Its size can vary up to 256 bytes.

Kernel device identifier

The kernel device identifier is an 8-byte identifier computed from the CII and the CSDD. It is unique across all devices, consistent across reboots, and identical from one computer to another for the same device. It is only meant for internal use by the sys::hw service, which generates an UDI for external use.

Raw device descriptor

The raw device descriptor (RDD) is a data structure (up to 260 bytes) made of the followings:

  • KDI (8 bytes)
  • CII (4 bytes)
  • Size of the CSDD, in bytes (1 byte)
  • CSDD (up to 256 bytes)

This descriptor is then used by the sys::hw service to expose the device to the rest of the operating system.

Input/output ports

The kernel first detects the I/O ports used by each device, and maps it to the device's KDI.

They are uni-directionals and as such are split in two categories: input ports and output ports.

Input ports are used by devices to transmit informations to the kernel. When this happens, the data is put on a stack, and drivers can then retrieve it using the READ_IO_PORT system call.

Output ports are used by drivers to transmit informations to devices, using the WRITE_IO_PORT system call.

I/O ports identifiers

I/O ports are accessed using relative identifiers, which corresponds to the nth port of the physical device, meaning it starts to 0 and ends to <number of ports in the device> - 1. The kernel transparently translates the relative identifier to the real port number.

The association with the real port number is transparently performed by the kernel.

Drivers

A driver is a process which can directly communicate with hardware devices using the dedicated system calls.

They communicate with external processes through the sys::hw system service, or sys::fs when direct driver access is possible.

You can find more about how drivers work in this section.

Direct communication with device hardwares is made through system calls.

The sys::hw service is considered as a driver for all devices.

Kernel communication

The kernel does not identify devices, as this task is relegated to the sys::hw service. In order to communicate with hardware devices, only the CII is provided.