1*4882a593Smuzhiyun======================= 2*4882a593SmuzhiyunThe Frame Buffer Device 3*4882a593Smuzhiyun======================= 4*4882a593Smuzhiyun 5*4882a593SmuzhiyunLast revised: May 10, 2001 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun0. Introduction 9*4882a593Smuzhiyun--------------- 10*4882a593Smuzhiyun 11*4882a593SmuzhiyunThe frame buffer device provides an abstraction for the graphics hardware. It 12*4882a593Smuzhiyunrepresents the frame buffer of some video hardware and allows application 13*4882a593Smuzhiyunsoftware to access the graphics hardware through a well-defined interface, so 14*4882a593Smuzhiyunthe software doesn't need to know anything about the low-level (hardware 15*4882a593Smuzhiyunregister) stuff. 16*4882a593Smuzhiyun 17*4882a593SmuzhiyunThe device is accessed through special device nodes, usually located in the 18*4882a593Smuzhiyun/dev directory, i.e. /dev/fb*. 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun1. User's View of /dev/fb* 22*4882a593Smuzhiyun-------------------------- 23*4882a593Smuzhiyun 24*4882a593SmuzhiyunFrom the user's point of view, the frame buffer device looks just like any 25*4882a593Smuzhiyunother device in /dev. It's a character device using major 29; the minor 26*4882a593Smuzhiyunspecifies the frame buffer number. 27*4882a593Smuzhiyun 28*4882a593SmuzhiyunBy convention, the following device nodes are used (numbers indicate the device 29*4882a593Smuzhiyunminor numbers):: 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun 0 = /dev/fb0 First frame buffer 32*4882a593Smuzhiyun 1 = /dev/fb1 Second frame buffer 33*4882a593Smuzhiyun ... 34*4882a593Smuzhiyun 31 = /dev/fb31 32nd frame buffer 35*4882a593Smuzhiyun 36*4882a593SmuzhiyunFor backwards compatibility, you may want to create the following symbolic 37*4882a593Smuzhiyunlinks:: 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun /dev/fb0current -> fb0 40*4882a593Smuzhiyun /dev/fb1current -> fb1 41*4882a593Smuzhiyun 42*4882a593Smuzhiyunand so on... 43*4882a593Smuzhiyun 44*4882a593SmuzhiyunThe frame buffer devices are also `normal` memory devices, this means, you can 45*4882a593Smuzhiyunread and write their contents. You can, for example, make a screen snapshot by:: 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun cp /dev/fb0 myfile 48*4882a593Smuzhiyun 49*4882a593SmuzhiyunThere also can be more than one frame buffer at a time, e.g. if you have a 50*4882a593Smuzhiyungraphics card in addition to the built-in hardware. The corresponding frame 51*4882a593Smuzhiyunbuffer devices (/dev/fb0 and /dev/fb1 etc.) work independently. 52*4882a593Smuzhiyun 53*4882a593SmuzhiyunApplication software that uses the frame buffer device (e.g. the X server) will 54*4882a593Smuzhiyunuse /dev/fb0 by default (older software uses /dev/fb0current). You can specify 55*4882a593Smuzhiyunan alternative frame buffer device by setting the environment variable 56*4882a593Smuzhiyun$FRAMEBUFFER to the path name of a frame buffer device, e.g. (for sh/bash 57*4882a593Smuzhiyunusers):: 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun export FRAMEBUFFER=/dev/fb1 60*4882a593Smuzhiyun 61*4882a593Smuzhiyunor (for csh users):: 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun setenv FRAMEBUFFER /dev/fb1 64*4882a593Smuzhiyun 65*4882a593SmuzhiyunAfter this the X server will use the second frame buffer. 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun2. Programmer's View of /dev/fb* 69*4882a593Smuzhiyun-------------------------------- 70*4882a593Smuzhiyun 71*4882a593SmuzhiyunAs you already know, a frame buffer device is a memory device like /dev/mem and 72*4882a593Smuzhiyunit has the same features. You can read it, write it, seek to some location in 73*4882a593Smuzhiyunit and mmap() it (the main usage). The difference is just that the memory that 74*4882a593Smuzhiyunappears in the special file is not the whole memory, but the frame buffer of 75*4882a593Smuzhiyunsome video hardware. 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun/dev/fb* also allows several ioctls on it, by which lots of information about 78*4882a593Smuzhiyunthe hardware can be queried and set. The color map handling works via ioctls, 79*4882a593Smuzhiyuntoo. Look into <linux/fb.h> for more information on what ioctls exist and on 80*4882a593Smuzhiyunwhich data structures they work. Here's just a brief overview: 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun - You can request unchangeable information about the hardware, like name, 83*4882a593Smuzhiyun organization of the screen memory (planes, packed pixels, ...) and address 84*4882a593Smuzhiyun and length of the screen memory. 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun - You can request and change variable information about the hardware, like 87*4882a593Smuzhiyun visible and virtual geometry, depth, color map format, timing, and so on. 88*4882a593Smuzhiyun If you try to change that information, the driver maybe will round up some 89*4882a593Smuzhiyun values to meet the hardware's capabilities (or return EINVAL if that isn't 90*4882a593Smuzhiyun possible). 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun - You can get and set parts of the color map. Communication is done with 16 93*4882a593Smuzhiyun bits per color part (red, green, blue, transparency) to support all 94*4882a593Smuzhiyun existing hardware. The driver does all the computations needed to apply 95*4882a593Smuzhiyun it to the hardware (round it down to less bits, maybe throw away 96*4882a593Smuzhiyun transparency). 97*4882a593Smuzhiyun 98*4882a593SmuzhiyunAll this hardware abstraction makes the implementation of application programs 99*4882a593Smuzhiyuneasier and more portable. E.g. the X server works completely on /dev/fb* and 100*4882a593Smuzhiyunthus doesn't need to know, for example, how the color registers of the concrete 101*4882a593Smuzhiyunhardware are organized. XF68_FBDev is a general X server for bitmapped, 102*4882a593Smuzhiyununaccelerated video hardware. The only thing that has to be built into 103*4882a593Smuzhiyunapplication programs is the screen organization (bitplanes or chunky pixels 104*4882a593Smuzhiyunetc.), because it works on the frame buffer image data directly. 105*4882a593Smuzhiyun 106*4882a593SmuzhiyunFor the future it is planned that frame buffer drivers for graphics cards and 107*4882a593Smuzhiyunthe like can be implemented as kernel modules that are loaded at runtime. Such 108*4882a593Smuzhiyuna driver just has to call register_framebuffer() and supply some functions. 109*4882a593SmuzhiyunWriting and distributing such drivers independently from the kernel will save 110*4882a593Smuzhiyunmuch trouble... 111*4882a593Smuzhiyun 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun3. Frame Buffer Resolution Maintenance 114*4882a593Smuzhiyun-------------------------------------- 115*4882a593Smuzhiyun 116*4882a593SmuzhiyunFrame buffer resolutions are maintained using the utility `fbset`. It can 117*4882a593Smuzhiyunchange the video mode properties of a frame buffer device. Its main usage is 118*4882a593Smuzhiyunto change the current video mode, e.g. during boot up in one of your `/etc/rc.*` 119*4882a593Smuzhiyunor `/etc/init.d/*` files. 120*4882a593Smuzhiyun 121*4882a593SmuzhiyunFbset uses a video mode database stored in a configuration file, so you can 122*4882a593Smuzhiyuneasily add your own modes and refer to them with a simple identifier. 123*4882a593Smuzhiyun 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun4. The X Server 126*4882a593Smuzhiyun--------------- 127*4882a593Smuzhiyun 128*4882a593SmuzhiyunThe X server (XF68_FBDev) is the most notable application program for the frame 129*4882a593Smuzhiyunbuffer device. Starting with XFree86 release 3.2, the X server is part of 130*4882a593SmuzhiyunXFree86 and has 2 modes: 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun - If the `Display` subsection for the `fbdev` driver in the /etc/XF86Config 133*4882a593Smuzhiyun file contains a:: 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun Modes "default" 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun line, the X server will use the scheme discussed above, i.e. it will start 138*4882a593Smuzhiyun up in the resolution determined by /dev/fb0 (or $FRAMEBUFFER, if set). You 139*4882a593Smuzhiyun still have to specify the color depth (using the Depth keyword) and virtual 140*4882a593Smuzhiyun resolution (using the Virtual keyword) though. This is the default for the 141*4882a593Smuzhiyun configuration file supplied with XFree86. It's the most simple 142*4882a593Smuzhiyun configuration, but it has some limitations. 143*4882a593Smuzhiyun 144*4882a593Smuzhiyun - Therefore it's also possible to specify resolutions in the /etc/XF86Config 145*4882a593Smuzhiyun file. This allows for on-the-fly resolution switching while retaining the 146*4882a593Smuzhiyun same virtual desktop size. The frame buffer device that's used is still 147*4882a593Smuzhiyun /dev/fb0current (or $FRAMEBUFFER), but the available resolutions are 148*4882a593Smuzhiyun defined by /etc/XF86Config now. The disadvantage is that you have to 149*4882a593Smuzhiyun specify the timings in a different format (but `fbset -x` may help). 150*4882a593Smuzhiyun 151*4882a593SmuzhiyunTo tune a video mode, you can use fbset or xvidtune. Note that xvidtune doesn't 152*4882a593Smuzhiyunwork 100% with XF68_FBDev: the reported clock values are always incorrect. 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun 155*4882a593Smuzhiyun5. Video Mode Timings 156*4882a593Smuzhiyun--------------------- 157*4882a593Smuzhiyun 158*4882a593SmuzhiyunA monitor draws an image on the screen by using an electron beam (3 electron 159*4882a593Smuzhiyunbeams for color models, 1 electron beam for monochrome monitors). The front of 160*4882a593Smuzhiyunthe screen is covered by a pattern of colored phosphors (pixels). If a phosphor 161*4882a593Smuzhiyunis hit by an electron, it emits a photon and thus becomes visible. 162*4882a593Smuzhiyun 163*4882a593SmuzhiyunThe electron beam draws horizontal lines (scanlines) from left to right, and 164*4882a593Smuzhiyunfrom the top to the bottom of the screen. By modifying the intensity of the 165*4882a593Smuzhiyunelectron beam, pixels with various colors and intensities can be shown. 166*4882a593Smuzhiyun 167*4882a593SmuzhiyunAfter each scanline the electron beam has to move back to the left side of the 168*4882a593Smuzhiyunscreen and to the next line: this is called the horizontal retrace. After the 169*4882a593Smuzhiyunwhole screen (frame) was painted, the beam moves back to the upper left corner: 170*4882a593Smuzhiyunthis is called the vertical retrace. During both the horizontal and vertical 171*4882a593Smuzhiyunretrace, the electron beam is turned off (blanked). 172*4882a593Smuzhiyun 173*4882a593SmuzhiyunThe speed at which the electron beam paints the pixels is determined by the 174*4882a593Smuzhiyundotclock in the graphics board. For a dotclock of e.g. 28.37516 MHz (millions 175*4882a593Smuzhiyunof cycles per second), each pixel is 35242 ps (picoseconds) long:: 176*4882a593Smuzhiyun 177*4882a593Smuzhiyun 1/(28.37516E6 Hz) = 35.242E-9 s 178*4882a593Smuzhiyun 179*4882a593SmuzhiyunIf the screen resolution is 640x480, it will take:: 180*4882a593Smuzhiyun 181*4882a593Smuzhiyun 640*35.242E-9 s = 22.555E-6 s 182*4882a593Smuzhiyun 183*4882a593Smuzhiyunto paint the 640 (xres) pixels on one scanline. But the horizontal retrace 184*4882a593Smuzhiyunalso takes time (e.g. 272 `pixels`), so a full scanline takes:: 185*4882a593Smuzhiyun 186*4882a593Smuzhiyun (640+272)*35.242E-9 s = 32.141E-6 s 187*4882a593Smuzhiyun 188*4882a593SmuzhiyunWe'll say that the horizontal scanrate is about 31 kHz:: 189*4882a593Smuzhiyun 190*4882a593Smuzhiyun 1/(32.141E-6 s) = 31.113E3 Hz 191*4882a593Smuzhiyun 192*4882a593SmuzhiyunA full screen counts 480 (yres) lines, but we have to consider the vertical 193*4882a593Smuzhiyunretrace too (e.g. 49 `lines`). So a full screen will take:: 194*4882a593Smuzhiyun 195*4882a593Smuzhiyun (480+49)*32.141E-6 s = 17.002E-3 s 196*4882a593Smuzhiyun 197*4882a593SmuzhiyunThe vertical scanrate is about 59 Hz:: 198*4882a593Smuzhiyun 199*4882a593Smuzhiyun 1/(17.002E-3 s) = 58.815 Hz 200*4882a593Smuzhiyun 201*4882a593SmuzhiyunThis means the screen data is refreshed about 59 times per second. To have a 202*4882a593Smuzhiyunstable picture without visible flicker, VESA recommends a vertical scanrate of 203*4882a593Smuzhiyunat least 72 Hz. But the perceived flicker is very human dependent: some people 204*4882a593Smuzhiyuncan use 50 Hz without any trouble, while I'll notice if it's less than 80 Hz. 205*4882a593Smuzhiyun 206*4882a593SmuzhiyunSince the monitor doesn't know when a new scanline starts, the graphics board 207*4882a593Smuzhiyunwill supply a synchronization pulse (horizontal sync or hsync) for each 208*4882a593Smuzhiyunscanline. Similarly it supplies a synchronization pulse (vertical sync or 209*4882a593Smuzhiyunvsync) for each new frame. The position of the image on the screen is 210*4882a593Smuzhiyuninfluenced by the moments at which the synchronization pulses occur. 211*4882a593Smuzhiyun 212*4882a593SmuzhiyunThe following picture summarizes all timings. The horizontal retrace time is 213*4882a593Smuzhiyunthe sum of the left margin, the right margin and the hsync length, while the 214*4882a593Smuzhiyunvertical retrace time is the sum of the upper margin, the lower margin and the 215*4882a593Smuzhiyunvsync length:: 216*4882a593Smuzhiyun 217*4882a593Smuzhiyun +----------+---------------------------------------------+----------+-------+ 218*4882a593Smuzhiyun | | ↑ | | | 219*4882a593Smuzhiyun | | |upper_margin | | | 220*4882a593Smuzhiyun | | ↓ | | | 221*4882a593Smuzhiyun +----------###############################################----------+-------+ 222*4882a593Smuzhiyun | # ↑ # | | 223*4882a593Smuzhiyun | # | # | | 224*4882a593Smuzhiyun | # | # | | 225*4882a593Smuzhiyun | # | # | | 226*4882a593Smuzhiyun | left # | # right | hsync | 227*4882a593Smuzhiyun | margin # | xres # margin | len | 228*4882a593Smuzhiyun |<-------->#<---------------+--------------------------->#<-------->|<----->| 229*4882a593Smuzhiyun | # | # | | 230*4882a593Smuzhiyun | # | # | | 231*4882a593Smuzhiyun | # | # | | 232*4882a593Smuzhiyun | # |yres # | | 233*4882a593Smuzhiyun | # | # | | 234*4882a593Smuzhiyun | # | # | | 235*4882a593Smuzhiyun | # | # | | 236*4882a593Smuzhiyun | # | # | | 237*4882a593Smuzhiyun | # | # | | 238*4882a593Smuzhiyun | # | # | | 239*4882a593Smuzhiyun | # | # | | 240*4882a593Smuzhiyun | # | # | | 241*4882a593Smuzhiyun | # ↓ # | | 242*4882a593Smuzhiyun +----------###############################################----------+-------+ 243*4882a593Smuzhiyun | | ↑ | | | 244*4882a593Smuzhiyun | | |lower_margin | | | 245*4882a593Smuzhiyun | | ↓ | | | 246*4882a593Smuzhiyun +----------+---------------------------------------------+----------+-------+ 247*4882a593Smuzhiyun | | ↑ | | | 248*4882a593Smuzhiyun | | |vsync_len | | | 249*4882a593Smuzhiyun | | ↓ | | | 250*4882a593Smuzhiyun +----------+---------------------------------------------+----------+-------+ 251*4882a593Smuzhiyun 252*4882a593SmuzhiyunThe frame buffer device expects all horizontal timings in number of dotclocks 253*4882a593Smuzhiyun(in picoseconds, 1E-12 s), and vertical timings in number of scanlines. 254*4882a593Smuzhiyun 255*4882a593Smuzhiyun 256*4882a593Smuzhiyun6. Converting XFree86 timing values info frame buffer device timings 257*4882a593Smuzhiyun-------------------------------------------------------------------- 258*4882a593Smuzhiyun 259*4882a593SmuzhiyunAn XFree86 mode line consists of the following fields:: 260*4882a593Smuzhiyun 261*4882a593Smuzhiyun "800x600" 50 800 856 976 1040 600 637 643 666 262*4882a593Smuzhiyun < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL 263*4882a593Smuzhiyun 264*4882a593SmuzhiyunThe frame buffer device uses the following fields: 265*4882a593Smuzhiyun 266*4882a593Smuzhiyun - pixclock: pixel clock in ps (pico seconds) 267*4882a593Smuzhiyun - left_margin: time from sync to picture 268*4882a593Smuzhiyun - right_margin: time from picture to sync 269*4882a593Smuzhiyun - upper_margin: time from sync to picture 270*4882a593Smuzhiyun - lower_margin: time from picture to sync 271*4882a593Smuzhiyun - hsync_len: length of horizontal sync 272*4882a593Smuzhiyun - vsync_len: length of vertical sync 273*4882a593Smuzhiyun 274*4882a593Smuzhiyun1) Pixelclock: 275*4882a593Smuzhiyun 276*4882a593Smuzhiyun xfree: in MHz 277*4882a593Smuzhiyun 278*4882a593Smuzhiyun fb: in picoseconds (ps) 279*4882a593Smuzhiyun 280*4882a593Smuzhiyun pixclock = 1000000 / DCF 281*4882a593Smuzhiyun 282*4882a593Smuzhiyun2) horizontal timings: 283*4882a593Smuzhiyun 284*4882a593Smuzhiyun left_margin = HFL - SH2 285*4882a593Smuzhiyun 286*4882a593Smuzhiyun right_margin = SH1 - HR 287*4882a593Smuzhiyun 288*4882a593Smuzhiyun hsync_len = SH2 - SH1 289*4882a593Smuzhiyun 290*4882a593Smuzhiyun3) vertical timings: 291*4882a593Smuzhiyun 292*4882a593Smuzhiyun upper_margin = VFL - SV2 293*4882a593Smuzhiyun 294*4882a593Smuzhiyun lower_margin = SV1 - VR 295*4882a593Smuzhiyun 296*4882a593Smuzhiyun vsync_len = SV2 - SV1 297*4882a593Smuzhiyun 298*4882a593SmuzhiyunGood examples for VESA timings can be found in the XFree86 source tree, 299*4882a593Smuzhiyununder "xc/programs/Xserver/hw/xfree86/doc/modeDB.txt". 300*4882a593Smuzhiyun 301*4882a593Smuzhiyun 302*4882a593Smuzhiyun7. References 303*4882a593Smuzhiyun------------- 304*4882a593Smuzhiyun 305*4882a593SmuzhiyunFor more specific information about the frame buffer device and its 306*4882a593Smuzhiyunapplications, please refer to the Linux-fbdev website: 307*4882a593Smuzhiyun 308*4882a593Smuzhiyun http://linux-fbdev.sourceforge.net/ 309*4882a593Smuzhiyun 310*4882a593Smuzhiyunand to the following documentation: 311*4882a593Smuzhiyun 312*4882a593Smuzhiyun - The manual pages for fbset: fbset(8), fb.modes(5) 313*4882a593Smuzhiyun - The manual pages for XFree86: XF68_FBDev(1), XF86Config(4/5) 314*4882a593Smuzhiyun - The mighty kernel sources: 315*4882a593Smuzhiyun 316*4882a593Smuzhiyun - linux/drivers/video/ 317*4882a593Smuzhiyun - linux/include/linux/fb.h 318*4882a593Smuzhiyun - linux/include/video/ 319*4882a593Smuzhiyun 320*4882a593Smuzhiyun 321*4882a593Smuzhiyun 322*4882a593Smuzhiyun8. Mailing list 323*4882a593Smuzhiyun--------------- 324*4882a593Smuzhiyun 325*4882a593SmuzhiyunThere is a frame buffer device related mailing list at kernel.org: 326*4882a593Smuzhiyunlinux-fbdev@vger.kernel.org. 327*4882a593Smuzhiyun 328*4882a593SmuzhiyunPoint your web browser to http://sourceforge.net/projects/linux-fbdev/ for 329*4882a593Smuzhiyunsubscription information and archive browsing. 330*4882a593Smuzhiyun 331*4882a593Smuzhiyun 332*4882a593Smuzhiyun9. Downloading 333*4882a593Smuzhiyun-------------- 334*4882a593Smuzhiyun 335*4882a593SmuzhiyunAll necessary files can be found at 336*4882a593Smuzhiyun 337*4882a593Smuzhiyun ftp://ftp.uni-erlangen.de/pub/Linux/LOCAL/680x0/ 338*4882a593Smuzhiyun 339*4882a593Smuzhiyunand on its mirrors. 340*4882a593Smuzhiyun 341*4882a593SmuzhiyunThe latest version of fbset can be found at 342*4882a593Smuzhiyun 343*4882a593Smuzhiyun http://www.linux-fbdev.org/ 344*4882a593Smuzhiyun 345*4882a593Smuzhiyun 346*4882a593Smuzhiyun10. Credits 347*4882a593Smuzhiyun----------- 348*4882a593Smuzhiyun 349*4882a593SmuzhiyunThis readme was written by Geert Uytterhoeven, partly based on the original 350*4882a593Smuzhiyun`X-framebuffer.README` by Roman Hodek and Martin Schaller. Section 6 was 351*4882a593Smuzhiyunprovided by Frank Neumann. 352*4882a593Smuzhiyun 353*4882a593SmuzhiyunThe frame buffer device abstraction was designed by Martin Schaller. 354