The Frame Buffer Device

Last revised: May 10, 2001

0. Introduction

The frame buffer device provides an abstraction for the graphics hardware. Itrepresents the frame buffer of some video hardware and allows applicationsoftware to access the graphics hardware through a well-defined interface, sothe software doesn’t need to know anything about the low-level (hardwareregister) stuff.

The device is accessed through special device nodes, usually located in the/dev directory, i.e. /dev/fb*.

1. User’s View of /dev/fb*

From the user’s point of view, the frame buffer device looks just like anyother device in /dev. It’s a character device using major 29; the minorspecifies the frame buffer number.

By convention, the following device nodes are used (numbers indicate the deviceminor numbers):

 0 = /dev/fb0      First frame buffer 1 = /dev/fb1      Second frame buffer     ...31 = /dev/fb31     32nd frame buffer

For backwards compatibility, you may want to create the following symboliclinks:

/dev/fb0current -> fb0/dev/fb1current -> fb1

and so on…

The frame buffer devices are alsonormal memory devices, this means, you canread and write their contents. You can, for example, make a screen snapshot by:

cp /dev/fb0 myfile

There also can be more than one frame buffer at a time, e.g. if you have agraphics card in addition to the built-in hardware. The corresponding framebuffer devices (/dev/fb0 and /dev/fb1 etc.) work independently.

Application software that uses the frame buffer device (e.g. the X server) willuse /dev/fb0 by default (older software uses /dev/fb0current). You can specifyan alternative frame buffer device by setting the environment variable$FRAMEBUFFER to the path name of a frame buffer device, e.g. (for sh/bashusers):

export FRAMEBUFFER=/dev/fb1

or (for csh users):

setenv FRAMEBUFFER /dev/fb1

After this the X server will use the second frame buffer.

2. Programmer’s View of /dev/fb*

As you already know, a frame buffer device is a memory device like /dev/mem andit has the same features. You can read it, write it, seek to some location init and mmap() it (the main usage). The difference is just that the memory thatappears in the special file is not the whole memory, but the frame buffer ofsome video hardware.

/dev/fb* also allows several ioctls on it, by which lots of information aboutthe hardware can be queried and set. The color map handling works via ioctls,too. Look into <linux/fb.h> for more information on what ioctls exist and onwhich data structures they work. Here’s just a brief overview:

  • You can request unchangeable information about the hardware, like name,organization of the screen memory (planes, packed pixels, …) and addressand length of the screen memory.
  • You can request and change variable information about the hardware, likevisible and virtual geometry, depth, color map format, timing, and so on.If you try to change that information, the driver maybe will round up somevalues to meet the hardware’s capabilities (or return EINVAL if that isn’tpossible).
  • You can get and set parts of the color map. Communication is done with 16bits per color part (red, green, blue, transparency) to support allexisting hardware. The driver does all the computations needed to applyit to the hardware (round it down to less bits, maybe throw awaytransparency).

All this hardware abstraction makes the implementation of application programseasier and more portable. E.g. the X server works completely on /dev/fb* andthus doesn’t need to know, for example, how the color registers of the concretehardware are organized. XF68_FBDev is a general X server for bitmapped,unaccelerated video hardware. The only thing that has to be built intoapplication programs is the screen organization (bitplanes or chunky pixelsetc.), because it works on the frame buffer image data directly.

For the future it is planned that frame buffer drivers for graphics cards andthe like can be implemented as kernel modules that are loaded at runtime. Sucha driver just has to callregister_framebuffer() and supply some functions.Writing and distributing such drivers independently from the kernel will savemuch trouble…

3. Frame Buffer Resolution Maintenance

Frame buffer resolutions are maintained using the utilityfbset. It canchange the video mode properties of a frame buffer device. Its main usage isto change the current video mode, e.g. during boot up in one of your/etc/rc.*or/etc/init.d/* files.

Fbset uses a video mode database stored in a configuration file, so you caneasily add your own modes and refer to them with a simple identifier.

4. The X Server

The X server (XF68_FBDev) is the most notable application program for the framebuffer device. Starting with XFree86 release 3.2, the X server is part ofXFree86 and has 2 modes:

  • If theDisplay subsection for thefbdev driver in the /etc/XF86Configfile contains a:

    Modes "default"

    line, the X server will use the scheme discussed above, i.e. it will startup in the resolution determined by /dev/fb0 (or $FRAMEBUFFER, if set). Youstill have to specify the color depth (using the Depth keyword) and virtualresolution (using the Virtual keyword) though. This is the default for theconfiguration file supplied with XFree86. It’s the most simpleconfiguration, but it has some limitations.

  • Therefore it’s also possible to specify resolutions in the /etc/XF86Configfile. This allows for on-the-fly resolution switching while retaining thesame virtual desktop size. The frame buffer device that’s used is still/dev/fb0current (or $FRAMEBUFFER), but the available resolutions aredefined by /etc/XF86Config now. The disadvantage is that you have tospecify the timings in a different format (butfbset -x may help).

To tune a video mode, you can use fbset or xvidtune. Note that xvidtune doesn’twork 100% with XF68_FBDev: the reported clock values are always incorrect.

5. Video Mode Timings

A monitor draws an image on the screen by using an electron beam (3 electronbeams for color models, 1 electron beam for monochrome monitors). The front ofthe screen is covered by a pattern of colored phosphors (pixels). If a phosphoris hit by an electron, it emits a photon and thus becomes visible.

The electron beam draws horizontal lines (scanlines) from left to right, andfrom the top to the bottom of the screen. By modifying the intensity of theelectron beam, pixels with various colors and intensities can be shown.

After each scanline the electron beam has to move back to the left side of thescreen and to the next line: this is called the horizontal retrace. After thewhole screen (frame) was painted, the beam moves back to the upper left corner:this is called the vertical retrace. During both the horizontal and verticalretrace, the electron beam is turned off (blanked).

The speed at which the electron beam paints the pixels is determined by thedotclock in the graphics board. For a dotclock of e.g. 28.37516 MHz (millionsof cycles per second), each pixel is 35242 ps (picoseconds) long:

1/(28.37516E6 Hz) = 35.242E-9 s

If the screen resolution is 640x480, it will take:

640*35.242E-9 s = 22.555E-6 s

to paint the 640 (xres) pixels on one scanline. But the horizontal retracealso takes time (e.g. 272pixels), so a full scanline takes:

(640+272)*35.242E-9 s = 32.141E-6 s

We’ll say that the horizontal scanrate is about 31 kHz:

1/(32.141E-6 s) = 31.113E3 Hz

A full screen counts 480 (yres) lines, but we have to consider the verticalretrace too (e.g. 49lines). So a full screen will take:

(480+49)*32.141E-6 s = 17.002E-3 s

The vertical scanrate is about 59 Hz:

1/(17.002E-3 s) = 58.815 Hz

This means the screen data is refreshed about 59 times per second. To have astable picture without visible flicker, VESA recommends a vertical scanrate ofat least 72 Hz. But the perceived flicker is very human dependent: some peoplecan use 50 Hz without any trouble, while I’ll notice if it’s less than 80 Hz.

Since the monitor doesn’t know when a new scanline starts, the graphics boardwill supply a synchronization pulse (horizontal sync or hsync) for eachscanline. Similarly it supplies a synchronization pulse (vertical sync orvsync) for each new frame. The position of the image on the screen isinfluenced by the moments at which the synchronization pulses occur.

The following picture summarizes all timings. The horizontal retrace time isthe sum of the left margin, the right margin and the hsync length, while thevertical retrace time is the sum of the upper margin, the lower margin and thevsync length:

+----------+---------------------------------------------+----------+-------+|          |                ↑                            |          |       ||          |                |upper_margin                |          |       ||          |                ↓                            |          |       |+----------###############################################----------+-------+|          #                ↑                            #          |       ||          #                |                            #          |       ||          #                |                            #          |       ||          #                |                            #          |       ||   left   #                |                            #  right   | hsync ||  margin  #                |       xres                 #  margin  |  len  ||<-------->#<---------------+--------------------------->#<-------->|<----->||          #                |                            #          |       ||          #                |                            #          |       ||          #                |                            #          |       ||          #                |yres                        #          |       ||          #                |                            #          |       ||          #                |                            #          |       ||          #                |                            #          |       ||          #                |                            #          |       ||          #                |                            #          |       ||          #                |                            #          |       ||          #                |                            #          |       ||          #                |                            #          |       ||          #                ↓                            #          |       |+----------###############################################----------+-------+|          |                ↑                            |          |       ||          |                |lower_margin                |          |       ||          |                ↓                            |          |       |+----------+---------------------------------------------+----------+-------+|          |                ↑                            |          |       ||          |                |vsync_len                   |          |       ||          |                ↓                            |          |       |+----------+---------------------------------------------+----------+-------+

The frame buffer device expects all horizontal timings in number of dotclocks(in picoseconds, 1E-12 s), and vertical timings in number of scanlines.

6. Converting XFree86 timing values info frame buffer device timings

An XFree86 mode line consists of the following fields:

"800x600"     50      800  856  976 1040    600  637  643  666< name >     DCF       HR  SH1  SH2  HFL     VR  SV1  SV2  VFL

The frame buffer device uses the following fields:

  • pixclock: pixel clock in ps (pico seconds)
  • left_margin: time from sync to picture
  • right_margin: time from picture to sync
  • upper_margin: time from sync to picture
  • lower_margin: time from picture to sync
  • hsync_len: length of horizontal sync
  • vsync_len: length of vertical sync
  1. Pixelclock:

    xfree: in MHz

    fb: in picoseconds (ps)

    pixclock = 1000000 / DCF

  2. horizontal timings:

    left_margin = HFL - SH2

    right_margin = SH1 - HR

    hsync_len = SH2 - SH1

  3. vertical timings:

    upper_margin = VFL - SV2

    lower_margin = SV1 - VR

    vsync_len = SV2 - SV1

Good examples for VESA timings can be found in the XFree86 source tree,under “xc/programs/Xserver/hw/xfree86/doc/modeDB.txt”.

7. References

For more specific information about the frame buffer device and itsapplications, please refer to the Linux-fbdev website:

and to the following documentation:

  • The manual pages for fbset: fbset(8), fb.modes(5)

  • The manual pages for XFree86: XF68_FBDev(1), XF86Config(4/5)

  • The mighty kernel sources:

    • linux/drivers/video/
    • linux/include/linux/fb.h
    • linux/include/video/

8. Mailing list

There is a frame buffer device related mailing list at kernel.org:linux-fbdev@vger.kernel.org.

Point your web browser tohttp://sourceforge.net/projects/linux-fbdev/ forsubscription information and archive browsing.

9. Downloading

All necessary files can be found at

and on its mirrors.

The latest version of fbset can be found at

10. Credits

This readme was written by Geert Uytterhoeven, partly based on the originalX-framebuffer.README by Roman Hodek and Martin Schaller. Section 6 wasprovided by Frank Neumann.

The frame buffer device abstraction was designed by Martin Schaller.