Back to home page

OSCL-LXR

 
 

    


0001 =======================
0002 The Frame Buffer Device
0003 =======================
0004 
0005 Last revised: May 10, 2001
0006 
0007 
0008 0. Introduction
0009 ---------------
0010 
0011 The frame buffer device provides an abstraction for the graphics hardware. It
0012 represents the frame buffer of some video hardware and allows application
0013 software to access the graphics hardware through a well-defined interface, so
0014 the software doesn't need to know anything about the low-level (hardware
0015 register) stuff.
0016 
0017 The device is accessed through special device nodes, usually located in the
0018 /dev directory, i.e. /dev/fb*.
0019 
0020 
0021 1. User's View of /dev/fb*
0022 --------------------------
0023 
0024 From the user's point of view, the frame buffer device looks just like any
0025 other device in /dev. It's a character device using major 29; the minor
0026 specifies the frame buffer number.
0027 
0028 By convention, the following device nodes are used (numbers indicate the device
0029 minor numbers)::
0030 
0031       0 = /dev/fb0      First frame buffer
0032       1 = /dev/fb1      Second frame buffer
0033           ...
0034      31 = /dev/fb31     32nd frame buffer
0035 
0036 For backwards compatibility, you may want to create the following symbolic
0037 links::
0038 
0039     /dev/fb0current -> fb0
0040     /dev/fb1current -> fb1
0041 
0042 and so on...
0043 
0044 The frame buffer devices are also `normal` memory devices, this means, you can
0045 read and write their contents. You can, for example, make a screen snapshot by::
0046 
0047   cp /dev/fb0 myfile
0048 
0049 There also can be more than one frame buffer at a time, e.g. if you have a
0050 graphics card in addition to the built-in hardware. The corresponding frame
0051 buffer devices (/dev/fb0 and /dev/fb1 etc.) work independently.
0052 
0053 Application software that uses the frame buffer device (e.g. the X server) will
0054 use /dev/fb0 by default (older software uses /dev/fb0current). You can specify
0055 an alternative frame buffer device by setting the environment variable
0056 $FRAMEBUFFER to the path name of a frame buffer device, e.g. (for sh/bash
0057 users)::
0058 
0059     export FRAMEBUFFER=/dev/fb1
0060 
0061 or (for csh users)::
0062 
0063     setenv FRAMEBUFFER /dev/fb1
0064 
0065 After this the X server will use the second frame buffer.
0066 
0067 
0068 2. Programmer's View of /dev/fb*
0069 --------------------------------
0070 
0071 As you already know, a frame buffer device is a memory device like /dev/mem and
0072 it has the same features. You can read it, write it, seek to some location in
0073 it and mmap() it (the main usage). The difference is just that the memory that
0074 appears in the special file is not the whole memory, but the frame buffer of
0075 some video hardware.
0076 
0077 /dev/fb* also allows several ioctls on it, by which lots of information about
0078 the hardware can be queried and set. The color map handling works via ioctls,
0079 too. Look into <linux/fb.h> for more information on what ioctls exist and on
0080 which data structures they work. Here's just a brief overview:
0081 
0082   - You can request unchangeable information about the hardware, like name,
0083     organization of the screen memory (planes, packed pixels, ...) and address
0084     and length of the screen memory.
0085 
0086   - You can request and change variable information about the hardware, like
0087     visible and virtual geometry, depth, color map format, timing, and so on.
0088     If you try to change that information, the driver maybe will round up some
0089     values to meet the hardware's capabilities (or return EINVAL if that isn't
0090     possible).
0091 
0092   - You can get and set parts of the color map. Communication is done with 16
0093     bits per color part (red, green, blue, transparency) to support all
0094     existing hardware. The driver does all the computations needed to apply
0095     it to the hardware (round it down to less bits, maybe throw away
0096     transparency).
0097 
0098 All this hardware abstraction makes the implementation of application programs
0099 easier and more portable. E.g. the X server works completely on /dev/fb* and
0100 thus doesn't need to know, for example, how the color registers of the concrete
0101 hardware are organized. XF68_FBDev is a general X server for bitmapped,
0102 unaccelerated video hardware. The only thing that has to be built into
0103 application programs is the screen organization (bitplanes or chunky pixels
0104 etc.), because it works on the frame buffer image data directly.
0105 
0106 For the future it is planned that frame buffer drivers for graphics cards and
0107 the like can be implemented as kernel modules that are loaded at runtime. Such
0108 a driver just has to call register_framebuffer() and supply some functions.
0109 Writing and distributing such drivers independently from the kernel will save
0110 much trouble...
0111 
0112 
0113 3. Frame Buffer Resolution Maintenance
0114 --------------------------------------
0115 
0116 Frame buffer resolutions are maintained using the utility `fbset`. It can
0117 change the video mode properties of a frame buffer device. Its main usage is
0118 to change the current video mode, e.g. during boot up in one of your `/etc/rc.*`
0119 or `/etc/init.d/*` files.
0120 
0121 Fbset uses a video mode database stored in a configuration file, so you can
0122 easily add your own modes and refer to them with a simple identifier.
0123 
0124 
0125 4. The X Server
0126 ---------------
0127 
0128 The X server (XF68_FBDev) is the most notable application program for the frame
0129 buffer device. Starting with XFree86 release 3.2, the X server is part of
0130 XFree86 and has 2 modes:
0131 
0132   - If the `Display` subsection for the `fbdev` driver in the /etc/XF86Config
0133     file contains a::
0134 
0135         Modes "default"
0136 
0137     line, the X server will use the scheme discussed above, i.e. it will start
0138     up in the resolution determined by /dev/fb0 (or $FRAMEBUFFER, if set). You
0139     still have to specify the color depth (using the Depth keyword) and virtual
0140     resolution (using the Virtual keyword) though. This is the default for the
0141     configuration file supplied with XFree86. It's the most simple
0142     configuration, but it has some limitations.
0143 
0144   - Therefore it's also possible to specify resolutions in the /etc/XF86Config
0145     file. This allows for on-the-fly resolution switching while retaining the
0146     same virtual desktop size. The frame buffer device that's used is still
0147     /dev/fb0current (or $FRAMEBUFFER), but the available resolutions are
0148     defined by /etc/XF86Config now. The disadvantage is that you have to
0149     specify the timings in a different format (but `fbset -x` may help).
0150 
0151 To tune a video mode, you can use fbset or xvidtune. Note that xvidtune doesn't
0152 work 100% with XF68_FBDev: the reported clock values are always incorrect.
0153 
0154 
0155 5. Video Mode Timings
0156 ---------------------
0157 
0158 A monitor draws an image on the screen by using an electron beam (3 electron
0159 beams for color models, 1 electron beam for monochrome monitors). The front of
0160 the screen is covered by a pattern of colored phosphors (pixels). If a phosphor
0161 is hit by an electron, it emits a photon and thus becomes visible.
0162 
0163 The electron beam draws horizontal lines (scanlines) from left to right, and
0164 from the top to the bottom of the screen. By modifying the intensity of the
0165 electron beam, pixels with various colors and intensities can be shown.
0166 
0167 After each scanline the electron beam has to move back to the left side of the
0168 screen and to the next line: this is called the horizontal retrace. After the
0169 whole screen (frame) was painted, the beam moves back to the upper left corner:
0170 this is called the vertical retrace. During both the horizontal and vertical
0171 retrace, the electron beam is turned off (blanked).
0172 
0173 The speed at which the electron beam paints the pixels is determined by the
0174 dotclock in the graphics board. For a dotclock of e.g. 28.37516 MHz (millions
0175 of cycles per second), each pixel is 35242 ps (picoseconds) long::
0176 
0177     1/(28.37516E6 Hz) = 35.242E-9 s
0178 
0179 If the screen resolution is 640x480, it will take::
0180 
0181     640*35.242E-9 s = 22.555E-6 s
0182 
0183 to paint the 640 (xres) pixels on one scanline. But the horizontal retrace
0184 also takes time (e.g. 272 `pixels`), so a full scanline takes::
0185 
0186     (640+272)*35.242E-9 s = 32.141E-6 s
0187 
0188 We'll say that the horizontal scanrate is about 31 kHz::
0189 
0190     1/(32.141E-6 s) = 31.113E3 Hz
0191 
0192 A full screen counts 480 (yres) lines, but we have to consider the vertical
0193 retrace too (e.g. 49 `lines`). So a full screen will take::
0194 
0195     (480+49)*32.141E-6 s = 17.002E-3 s
0196 
0197 The vertical scanrate is about 59 Hz::
0198 
0199     1/(17.002E-3 s) = 58.815 Hz
0200 
0201 This means the screen data is refreshed about 59 times per second. To have a
0202 stable picture without visible flicker, VESA recommends a vertical scanrate of
0203 at least 72 Hz. But the perceived flicker is very human dependent: some people
0204 can use 50 Hz without any trouble, while I'll notice if it's less than 80 Hz.
0205 
0206 Since the monitor doesn't know when a new scanline starts, the graphics board
0207 will supply a synchronization pulse (horizontal sync or hsync) for each
0208 scanline.  Similarly it supplies a synchronization pulse (vertical sync or
0209 vsync) for each new frame. The position of the image on the screen is
0210 influenced by the moments at which the synchronization pulses occur.
0211 
0212 The following picture summarizes all timings. The horizontal retrace time is
0213 the sum of the left margin, the right margin and the hsync length, while the
0214 vertical retrace time is the sum of the upper margin, the lower margin and the
0215 vsync length::
0216 
0217   +----------+---------------------------------------------+----------+-------+
0218   |          |                ↑                            |          |       |
0219   |          |                |upper_margin                |          |       |
0220   |          |                ↓                            |          |       |
0221   +----------###############################################----------+-------+
0222   |          #                ↑                            #          |       |
0223   |          #                |                            #          |       |
0224   |          #                |                            #          |       |
0225   |          #                |                            #          |       |
0226   |   left   #                |                            #  right   | hsync |
0227   |  margin  #                |       xres                 #  margin  |  len  |
0228   |<-------->#<---------------+--------------------------->#<-------->|<----->|
0229   |          #                |                            #          |       |
0230   |          #                |                            #          |       |
0231   |          #                |                            #          |       |
0232   |          #                |yres                        #          |       |
0233   |          #                |                            #          |       |
0234   |          #                |                            #          |       |
0235   |          #                |                            #          |       |
0236   |          #                |                            #          |       |
0237   |          #                |                            #          |       |
0238   |          #                |                            #          |       |
0239   |          #                |                            #          |       |
0240   |          #                |                            #          |       |
0241   |          #                ↓                            #          |       |
0242   +----------###############################################----------+-------+
0243   |          |                ↑                            |          |       |
0244   |          |                |lower_margin                |          |       |
0245   |          |                ↓                            |          |       |
0246   +----------+---------------------------------------------+----------+-------+
0247   |          |                ↑                            |          |       |
0248   |          |                |vsync_len                   |          |       |
0249   |          |                ↓                            |          |       |
0250   +----------+---------------------------------------------+----------+-------+
0251 
0252 The frame buffer device expects all horizontal timings in number of dotclocks
0253 (in picoseconds, 1E-12 s), and vertical timings in number of scanlines.
0254 
0255 
0256 6. Converting XFree86 timing values info frame buffer device timings
0257 --------------------------------------------------------------------
0258 
0259 An XFree86 mode line consists of the following fields::
0260 
0261  "800x600"     50      800  856  976 1040    600  637  643  666
0262  < name >     DCF       HR  SH1  SH2  HFL     VR  SV1  SV2  VFL
0263 
0264 The frame buffer device uses the following fields:
0265 
0266   - pixclock: pixel clock in ps (pico seconds)
0267   - left_margin: time from sync to picture
0268   - right_margin: time from picture to sync
0269   - upper_margin: time from sync to picture
0270   - lower_margin: time from picture to sync
0271   - hsync_len: length of horizontal sync
0272   - vsync_len: length of vertical sync
0273 
0274 1) Pixelclock:
0275 
0276    xfree: in MHz
0277 
0278    fb: in picoseconds (ps)
0279 
0280    pixclock = 1000000 / DCF
0281 
0282 2) horizontal timings:
0283 
0284    left_margin = HFL - SH2
0285 
0286    right_margin = SH1 - HR
0287 
0288    hsync_len = SH2 - SH1
0289 
0290 3) vertical timings:
0291 
0292    upper_margin = VFL - SV2
0293 
0294    lower_margin = SV1 - VR
0295 
0296    vsync_len = SV2 - SV1
0297 
0298 Good examples for VESA timings can be found in the XFree86 source tree,
0299 under "xc/programs/Xserver/hw/xfree86/doc/modeDB.txt".
0300 
0301 
0302 7. References
0303 -------------
0304 
0305 For more specific information about the frame buffer device and its
0306 applications, please refer to the Linux-fbdev website:
0307 
0308     http://linux-fbdev.sourceforge.net/
0309 
0310 and to the following documentation:
0311 
0312   - The manual pages for fbset: fbset(8), fb.modes(5)
0313   - The manual pages for XFree86: XF68_FBDev(1), XF86Config(4/5)
0314   - The mighty kernel sources:
0315 
0316       - linux/drivers/video/
0317       - linux/include/linux/fb.h
0318       - linux/include/video/
0319 
0320 
0321 
0322 8. Mailing list
0323 ---------------
0324 
0325 There is a frame buffer device related mailing list at kernel.org:
0326 linux-fbdev@vger.kernel.org.
0327 
0328 Point your web browser to http://sourceforge.net/projects/linux-fbdev/ for
0329 subscription information and archive browsing.
0330 
0331 
0332 9. Downloading
0333 --------------
0334 
0335 All necessary files can be found at
0336 
0337     ftp://ftp.uni-erlangen.de/pub/Linux/LOCAL/680x0/
0338 
0339 and on its mirrors.
0340 
0341 The latest version of fbset can be found at
0342 
0343     http://www.linux-fbdev.org/
0344 
0345 
0346 10. Credits
0347 -----------
0348 
0349 This readme was written by Geert Uytterhoeven, partly based on the original
0350 `X-framebuffer.README` by Roman Hodek and Martin Schaller. Section 6 was
0351 provided by Frank Neumann.
0352 
0353 The frame buffer device abstraction was designed by Martin Schaller.