Writing an OS Kernel from Scratch | Display — From Framebuffer to GPU

Have you ever wondered: How is a single pixel lit up on the screen? The CPU only sends a few bytes of data, yet the display can render a complete Windows desktop or game scene. The chain in between — Framebuffer, DRM/KMS, GPU instructions — is deeper than you think.

This article starts from the basic principles of display, breaks down Framebuffer, display timing, DRM/KMS architecture, and finally provides reproducible Linux debugging commands.


I. Framebuffer: The Lowest-Level Display Memory

Framebuffer is the simplest abstraction in display hardware: a region of memory where each pixel corresponds to one or more bytes; CPU writes to memory equals writing to the screen.

Bash
  Pixel coordinates (0,0)  Pixel coordinates (1,0)  Pixel coordinates (2,0)
  ┌──────────┐  ┌──────────┐  ┌──────────┐
  │ R  G  B  │  │ R  G  B  │  │ R  G  B  │
  │08 16 24b │  │08 16 24b │  │08 16 24b │
  └──────────┘  └──────────┘  └──────────┘
  ←─── Horizontal scanline ───→

  Resolution 1920×1080 @ 60Hz
  → Each row: 1920 pixels, each frame: 1080 rows
  → Refresh: 60 frames per second
  → Bandwidth: 1920×1080×3×60373 MB/s (24bpp)

Framebuffer memory layout (RGB888, 24bpp):

Bash
0x0000: [B0][G0][R0][B1][G1][R1]...
       ←───── 3 bytes per pixel ─────→

Viewing Framebuffer in Linux:

Bash
$ cat /dev/fb0 | head -c 100  # Read Framebuffer content (raw pixel data)
$ fbset -s                    # View current display mode
mode "1920x1080-60"
    geometry 1920 1080 1920 1080 32
    timings 162 240 80 30 3 104 0
    accel true  rgba 8/16,8/8,8/0,0/0
$ ls /dev/fb*
/dev/fb0  /dev/fb1

II. Display Timing: HSync, VSync, and Pixel Clock

The display doesn’t directly show pixels — it scans line by line following a fixed timing sequence controlled by multiple signals:

Bash
  Horizontal Timing (one line):
  ───────────────────────────────────────────────────────
  │  Front   │  Sync  │  Back   │  Active Video          │
  │  Porch   │  Pulse │  Porch  │  (Active pixels)       │
  ───────────────────────────────────────────────────────
  │ ← HFP → │← HSP →│← HBP → │←─────── 1920 ─────→│

  Vertical Timing (one frame):
  ───────────────────────────────────────────────────────
  │ VFP │ VSync │ VBP │ Active Video │ Total 1080 rows
  ───────────────────────────────────────────────────────

Timing parameter explanations:

  • HFP/HBP/HSP: Horizontal front porch/back porch/sync pulse
  • VFP/VBP/VSP: Vertical front porch/back porch/sync pulse
  • Pixel Clock: Number of clock cycles per pixel

Calculating bandwidth:

Bash
Pixel Clock = 162 MHz (162 in timing)
Horizontal total = 1920 + 240 + 80 + 104 = 2344
Vertical total = 1080 + 30 + 3 + 23 = 1136
Refresh rate = 162 MHz / (2344 × 1136) ≈ 60.9 Hz
Effective bandwidth = 1920 × 1080 × 3 × 60373 MB/s

III. DRM/KMS: Modern Display Driver Architecture

Bash
DRM (Direct Rendering Manager) / KMS (Kernel Mode Setting):

User space:
  Applications → Wayland/X11 → libdrm → ioctl

Kernel space:
  ┌─────────────────────────────────────────────────┐
  │  DRM Core (drm.ko)                               │
  │  - GEM (Graphics Execution Manager)              │
  │  - KMS (Kernel Mode Setting)                     │
  │  - FBDEV compatibility layer                     │
  └──────────────────┬──────────────────────────────┘
                     │
  ┌──────────────────▼──────────────────────────────┐
  │  GPU Driver (amdgpu.ko / i915.ko / ...)          │
  │  - Command submission                            │
  │  - Memory management                             │
  │  - Display controller programming                │
  └─────────────────────────────────────────────────┘
                     │
                     ▼
              Hardware (GPU)

DRM objects:
  CRTC: Display controller (timing generation)
  Encoder: Signal encoding (LVDS/HDMI/DP)
  Connector: Physical connector status
  Plane: Hardware overlay layer
  FB: Framebuffer (memory buffer)

IV. Linux Debugging Commands

Bash
$ cat /sys/class/drm/card0-HDMI-A-1/modes  # Supported modes
$ modetest -M xlnx -c                       # Show DRM connectors
$ modetest -M xlnx -e                       # Show DRM encoders
$ modetest -M xlnx -p                       # Show DRM CRTCs
$ modetest -M xlnx -s 40:1920x1080-60       # Test mode-set
$ xrandr                                    # X11 display configuration
Last modified: 2024年3月6日

Author

Comments

Write a Reply or Comment

Your email address will not be published.