AOSP Framework & Internals
3 min read

Display Driver (DRM/KMS)

A technical overview of how Android pushes graphics buffers to the physical screen using the modern Linux DRM framework.

In the early days of Android, displaying graphics was handled by a primitive system called the Linux Framebuffer (fbdev). It was essentially a raw block of memory; if a user-space app wrote pixel colors into that memory, they appeared on the screen.

However, modern Android devices require hardware-accelerated composition, multiple display layers, VSYNC timing, and external displays. The primitive framebuffer could not handle this.

Modern Android devices exclusively use the DRM/KMS (Direct Rendering Manager / Kernel Mode Setting) framework.

The DRM/KMS Framework

The DRM framework is a massive Linux subsystem designed specifically for complex modern GPUs and display controllers. It is divided into two logical halves:

  1. DRM (Direct Rendering Manager): Handles the GPU side. It manages rendering commands, memory buffers (using GEM or ION/DMA-BUF), and context switching for hardware acceleration.
  2. KMS (Kernel Mode Setting): Handles the display side. It is responsible for configuring the display panel resolution, refresh rates, and pushing the final rendered buffers to the physical screen.

KMS Components

When bringing up a new display panel in Android, BSP (Board Support Package) engineers must configure several KMS components:

  • CRTC (CRT Controller): Represents the hardware block inside the SoC that scans data out to a screen. It controls the timing and VSYNC.
  • Encoder: Converts the raw pixel data from the CRTC into a specific electrical format (like MIPI DSI, HDMI, or DisplayPort).
  • Connector: Represents the physical port or soldered connection to the actual screen.

Display Panels (MIPI DSI)

The vast majority of smartphone displays use the MIPI DSI (Display Serial Interface) protocol.

Bringing up a new OLED panel in Android requires writing a specific DSI panel driver. This driver is usually a standard Platform Driver that sends a highly specific sequence of initialization commands over the DSI bus to wake up the screen, configure its internal registers, and turn on the backlight.

// Conceptual DSI panel initialization sequence in a kernel driver
static int my_panel_prepare(struct drm_panel *panel) {
    // 1. Turn on power regulators
    regulator_enable(vcc);
    
    // 2. Assert hardware reset pin via GPIO
    gpiod_set_value(reset_gpio, 1);
    msleep(20);
    gpiod_set_value(reset_gpio, 0);

    // 3. Send proprietary manufacturer init codes over DSI
    mipi_dsi_dcs_write_seq(dsi, 0x51, 0xFF); // Display brightness
    mipi_dsi_dcs_exit_sleep_mode(dsi);
    mipi_dsi_dcs_set_display_on(dsi);
    
    return 0;
}

Android Framework Integration

The Android user-space does not talk directly to the MIPI DSI driver.

  1. The Android SurfaceFlinger service composes the various app windows into a single image buffer.
  2. SurfaceFlinger passes this buffer to the Hardware Composer (HWC) HAL.
  3. The HWC HAL uses the libdrm user-space library to make ioctl calls to the kernel DRM driver.
  4. The KMS subsystem takes the buffer and pushes it to the DSI panel, synchronized with the hardware VSYNC signal to prevent screen tearing.
# You can check the active DRM state and connected displays via debugfs
adb shell cat /sys/kernel/debug/dri/0/state