On this page

DRM and Graphics

Linux has two graphics stacks: fbdev (1990s) simply writes pixels to video memory, while DRM (2010s+) provides a complete modern GPU interface—KMS handles display mode setting (atomic modesetting makes multi-monitor configurations atomic operations), GEM manages video memory allocation and cross-process sharing (DMA-BUF enables zero-copy buffer transfer between GPU and Wayland compositor). amdgpu and i915 are the largest consumers of these two subsystems. Kernel versions: 2.6 ~ 6.x

Overview

Linux has two graphics stacks: fbdev (framebuffer, 1990s) and DRM (Direct Rendering Manager, 2010s+). fbdev simply writes pixels to video memory—no GPU acceleration, no multi-plane compositing, no vsync synchronization. DRM provides a complete modern GPU interface: mode setting (KMS), memory management (GEM), GPU command submission (render), and cross-device buffer sharing (DMA-BUF).

From userspace, you see /dev/dri/card0 (primary GPU) and /dev/dri/renderD128 (render-only, does not require mode setting permissions). Mesa and Vulkan drivers communicate with the kernel through these device files.

Three Core DRM Subsystems

KMS (Kernel Mode Setting): Display Pipeline

KMS manages "how to get pixels to the monitor." The involved hardware abstractions are:

  • CRTC (Cathode Ray Tube Controller—a historical name retained): Scan controller that reads pixels from the framebuffer and generates video signals according to timing. Each CRTC drives one monitor.
  • Encoder: Encodes the pixel stream from the CRTC into a physical interface format (TMDS for HDMI, LVDS for laptop panels, DisplayPort).
  • Connector: Physical port (HDMI-A-1, DP-2, eDP-1). Detects monitor hot-plug (HPD) and reads EDID (monitor capability description: supported resolutions, refresh rates).
  • Plane: Overlay layer. Primary plane = main framebuffer. Overlay plane = hardware-accelerated overlay (video playback, mouse cursor). Modern GPUs have multiple planes for hardware compositing.

These objects form a pipeline: CRTC → Encoder → Connector. Userspace configures this pipeline via DRM_IOCTL_MODE_* ioctls.

Atomic Modesetting

The old API set parameters step-by-step—first change the CRTC mode, then the connector, etc.—and intermediate states at each step might flicker on the screen. Atomic modesetting encapsulates the entire display state into a drm_atomic_state structure:

// Construct an atomic commit:
struct drm_atomic_state *state = drm_atomic_state_alloc(dev);
// Add CRTC/plane/connector property modifications
drm_atomic_commit(state);
// → Validate (check) → If valid, apply atomically during vblank → No flickering transition

Key property: All-or-nothing—if validation fails (e.g., resolution not supported), the entire commit is rejected, and the display remains unchanged. This eliminates intermediate states where "the device is half-changed."

GEM (Graphics Execution Manager): Memory Management

GPU memory is not a simple malloc—it involves VRAM (video memory), GTT (Graphics Translation Table, partially visible system memory), and visibility constraints for different engines. GEM provides driver-agnostic buffer management:

// Allocate GPU buffer (driver-specific implementation):
struct drm_gem_object *obj = drm_gem_object_create(dev, size);
// → Returns handle → Userspace mmap → Access buffer contents

Key feature: DMA-BUF. GPU buffers can be exported as a file descriptor (drm_prime_handle_to_fd), and another GPU or V4L2 device can import it via that fd—enabling zero-copy cross-device sharing. Wayland compositors use this to send client-rendered buffers directly to the display engine without CPU copying.

GPU Driver Architecture: KMD + UMD Separation

Modern GPU drivers are divided into two parts:

KMD (Kernel Mode Driver): amdgpu.ko, i915.ko, nouveau.ko. Responsible for mode setting (display), memory management (GEM/TTM), command submission (ring buffer), fence synchronization, and firmware management.

UMD (User Mode Driver): Mesa (OpenGL/Vulkan) or NVIDIA's proprietary driver. Responsible for translating OpenGL/Vulkan APIs into GPU commands and shader compilation. Communicates via /dev/dri/renderD*—does not require mode setting permissions or root access.

The KMD provides infrastructure (allocating buffers, submitting commands), while the UMD provides the application API. This separation means Mesa can be updated independently of the kernel; new OpenGL versions do not require recompiling the kernel.

Migration from fbdev to DRM

fbdev is a 1990s framebuffer interface: mmap(fbdev_fd) obtains a video memory mapping, allowing direct pixel writes. It lacks vsync, multi-plane support, and GPU acceleration. Modern systems simulate the fbdev interface on top of DRM via drm_fb_helper—for compatibility with legacy programs (e.g., fbi, directfb). However, the underlying implementation remains DRM.

References

  • Source Code: drivers/gpu/drm/ (core), drivers/gpu/drm/amd/ (amdgpu), drivers/gpu/drm/i915/, include/drm/, include/uapi/drm/
  • Kernel Documentation: Documentation/gpu/
  • Mesa: docs.mesa3d.org

Keywords: DRM, KMS, GEM, atomic modesetting, CRTC, plane, DMA-BUF, amdgpu, i915, fbdev, Wayland