$linuxjunkies
>

The Linux Framebuffer Console

Understand Linux framebuffer internals, the fbdev-to-DRM/KMS evolution, and how to set a crisp high-resolution console with the right kernel parameters.

AdvancedUbuntuDebianFedoraArch11 min readUpdated June 7, 2026

Before you start

  • Root or sudo access on the target machine
  • Familiarity with editing bootloader configuration files
  • libdrm-tests (modetest) installed for mode enumeration
  • Basic understanding of Linux kernel parameters

The Linux framebuffer console sits at a curious crossroads: it predates modern graphics stacks by decades, yet remains relevant for headless servers, embedded systems, rescue environments, and anyone who wants a crisp high-resolution virtual terminal before a display server ever loads. Understanding it properly means understanding the evolution from raw fbdev to the DRM/KMS subsystem that replaced it—and knowing which layer you are actually talking to at any given moment.

What the Framebuffer Is

The Linux framebuffer (/dev/fb0, /dev/fb1, …) is a kernel abstraction that exposes a display device as a flat memory buffer. Userspace writes pixel data directly to that buffer and the hardware scans it out to the screen. No X server, no Wayland compositor, no GPU command queue—just memory-mapped pixels.

The kernel interface dates to 1997. It provides:

  • A character device at /dev/fbN
  • An ioctl API for querying and setting resolution, colour depth, and timing
  • A memory-mapped region for direct pixel writes

The classic user of this is fbcon, the in-kernel framebuffer console driver. When fbcon is active, virtual terminals (TTY1–TTY6) render text through the framebuffer rather than through the legacy VGA text-mode registers.

fbdev vs DRM/KMS

Modern Linux graphics are built on Direct Rendering Manager (DRM) and its Kernel Mode Setting (KMS) subsystem. DRM/KMS took over from raw fbdev around 2009–2010 and is now the authoritative path for every GPU from Intel, AMD, NVIDIA (open driver), and most SoC vendors.

The key differences matter in practice:

AspectLegacy fbdevDRM/KMS
Mode settingUserspace ioctl or BIOS vesafbKernel-owned, atomic
Multi-GPUFragile, separate devicesFirst-class via render nodes
Console integrationfbcon directlyfbcon via DRM's fbdev emulation layer, or simpledrm
Wayland/X compatibilityPoor (Weston fbdev backend, deprecated)Native
Suspend/resumeDriver-dependent, often brokenReliable atomic commits

When you boot a modern kernel, /dev/fb0 almost certainly comes from DRM's fbdev emulation layer—not a native fbdev driver. The DRM driver claims the hardware, then synthesises a /dev/fbN interface for legacy consumers. You can verify this:

cat /sys/class/graphics/fb0/device/driver/module/holders/*/name 2>/dev/null
# or more directly:
ls -l /sys/class/graphics/fb0

On a machine with the i915 or amdgpu driver, the symlink leads back into the DRM device tree.

simpledrm (merged in kernel 5.14) replaces the old simplefb fbdev driver for EFI/OF framebuffers handed off by firmware. It provides a proper DRM device from the very start of boot, giving a consistent console before vendor drivers load.

Console Resolution: Getting a Crisp TTY

The default Linux console on modern hardware is often stuck at a low resolution inherited from the EFI GOP framebuffer (commonly 1024×768 or 800×600). You can force the kernel to negotiate a specific mode using the video= kernel parameter.

Step 1: Find Available Modes

Before setting anything, check what the kernel reports as available:

cat /sys/class/graphics/fb0/modes

If that file is empty or absent, the DRM driver controls modes. Query it via:

# Requires modetest from libdrm-tests / libdrm-utils
modetest -c
# On Debian/Ubuntu:
sudo apt install libdrm-tests
# On Fedora:
sudo dnf install libdrm
# On Arch:
sudo pacman -S libdrm

Step 2: Set the Kernel Video Parameter

The video= parameter syntax is video=<connector>:<W>x<H>@<Hz>. For a typical laptop display:

video=eDP-1:1920x1080@60

For a desktop connected via HDMI:

video=HDMI-A-1:2560x1440@60

Connector names come from DRM. List them:

ls /sys/class/drm/ | grep -v render

Output will look like card0-HDMI-A-1, card0-eDP-1; strip the cardN- prefix for the video= value.

Step 3: Add to the Bootloader

GRUB (Debian/Ubuntu/Fedora/RHEL): Edit /etc/default/grub:

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash video=HDMI-A-1:1920x1080@60"
# Debian/Ubuntu:
sudo update-grub
# Fedora/RHEL/Rocky:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg

systemd-boot (Arch, modern Ubuntu, etc.): Edit your entry under /boot/loader/entries/:

options root=... rw quiet video=eDP-1:1920x1080@60

No update-grub equivalent needed; the file is read directly at boot.

Step 4: Font Scaling for HiDPI

A 4K framebuffer with an 8×16 font produces unreadably tiny text. The kernel's built-in fbcon supports font scaling. Add fbcon=font:TER16x32 to your kernel parameters for the Terminus 16×32 font (included in the kernel since 4.6):

video=eDP-1:3840x2160@60 fbcon=font:TER16x32

Alternatively, fbcon=rotate:1 rotates the console 90° for portrait monitors, and fbcon=map:0 pins all virtual consoles to /dev/fb0.

Step 5: Persistent Font via Console Setup (Distro Level)

For persistent font changes at the distro level (after the kernel hands off to userspace):

# Debian/Ubuntu: edit /etc/default/console-setup
FONTFACE="Terminus"
FONTSIZE="16x32"
# then:
sudo dpkg-reconfigure console-setup
# Arch: edit /etc/vconsole.conf
FONT=ter-132b
# ter-132b = Terminus bold 32px; install terminus-font package
# Fedora/RHEL: same vconsole.conf approach
echo 'FONT=latarcyrheb-sun32' | sudo tee /etc/vconsole.conf
sudo systemctl restart systemd-vconsole-setup

Verification

After rebooting with new parameters, confirm the active framebuffer resolution:

cat /sys/class/graphics/fb0/virtual_size
# e.g.: 1920,1080
# Check what fbcon reports via the kernel ring buffer:
sudo dmesg | grep -i 'fbcon\|drm\|fb0'

Look for lines such as Console: switching to colour frame buffer device 240x67—240×67 characters at 8×16 font equals 1920×1072, confirming the mode took.

Modern Relevance

The framebuffer console is far from obsolete. Practical use cases today include:

  • Servers and headless systems: A readable console over IPMI/BMC remote KVM is invaluable. Getting the resolution right during boot saves time when SSH is unavailable.
  • Embedded and SBC (Single-Board Computer) platforms: Raspberry Pi, Rockchip, and Allwinner boards use DRM/KMS with a framebuffer console as their primary display path. No desktop environment required.
  • Rescue environments: Live ISOs and initramfs rescue shells run entirely in the framebuffer console. A legible font at correct resolution matters when diagnosing disk failures at 2 AM.
  • Early-boot splash screens: Plymouth renders on the DRM framebuffer before the display server starts, then hands off cleanly via KMS.
  • Security posture: Minimal servers with no display server attack surface at all use the framebuffer console as their only graphical interface.

Note that Wayland compositors cannot use /dev/fb0 directly in any production-supported path; they require DRM/KMS. If you are building an embedded kiosk and considering fbdev as your Weston backend, understand that it was deprecated in Weston 9.0 and removed in later releases. Use the DRM backend instead.

Troubleshooting

Console stays at low resolution despite kernel parameter

Confirm the connector name is exact. A mismatch (e.g., HDMI-1 vs HDMI-A-1) causes the parameter to be silently ignored. Double-check with ls /sys/class/drm/. Also verify your bootloader actually passed the parameter: cat /proc/cmdline after boot.

/dev/fb0 missing entirely

The DRM driver may have loaded without fbdev emulation. On kernels 6.x+, check whether CONFIG_DRM_FBDEV_EMULATION was compiled in or as a module: grep DRM_FBDEV /boot/config-$(uname -r). Some minimal/server kernels omit it. The console still works via the simpledrm KMS path even without /dev/fb0.

Garbled or black screen after setting video parameter

The monitor may not support the requested mode. Boot with nomodeset temporarily to recover, then choose a mode confirmed by modetest -c. Avoid forcing reduced-blanking timings unless your cable and monitor explicitly support them.

Font change not persisting

On systemd systems, systemd-vconsole-setup.service applies the font at boot from /etc/vconsole.conf. Run systemctl status systemd-vconsole-setup to see if it errored. Missing font packages are the most common cause—install terminus-font (Arch/Fedora) or fonts-terminus (Debian/Ubuntu) before referencing those fonts.

tested on:Ubuntu 24.04Fedora 40Arch rollingDebian 12

Frequently asked questions

Is /dev/fb0 the same as the DRM device?
No. /dev/fb0 is a legacy interface; on modern systems it is synthesised by DRM's fbdev emulation layer on top of the real DRM device (e.g. /dev/dri/card0). They ultimately talk to the same hardware, but DRM is the authoritative owner.
Can I use the framebuffer console alongside a Wayland compositor?
Yes, but separately. Wayland compositors use DRM/KMS directly and take exclusive control of the display when running. The framebuffer console is active on TTYs not owned by the compositor, and you switch between them with Ctrl+Alt+F keys.
What does nomodeset actually do?
It tells the kernel not to load DRM KMS drivers and to fall back to a basic VESA/EFI framebuffer mode. This is useful for recovery but gives you a low-resolution console and no hardware acceleration.
Why does my resolution revert after the display server starts?
The display server (X.org or Wayland compositor) takes over DRM and sets its own resolution via atomic KMS commits. The console resolution only matters for TTYs running outside the display server session.
Is fbdev development still active upstream?
Barely. The kernel maintainers have been on a long deprecation path for native fbdev drivers; most have been superseded by DRM drivers. The fbcon layer itself is maintained because it is still the only in-kernel text console, but new fbdev device drivers are strongly discouraged upstream.

Related guides