4. Using framebuffer devices on x86 platforms

4.1. What is vesafb?

Vesafb is a framebuffer driver for x86 architecture that works with VESA 2.0 compliant graphic cards. It is closely related to the framebuffer device drivers in the kernel.

vesafb is a display driver that enables the use of graphical modes on your x86 platform for bitmapped text consoles. It can also display a logo, which is probably the main reason why you'd want to use vesafb :o)

Unfortunately, you can not use vesafb successfully with VESA 1.2 cards. This is because these 1.2 cards do not use linear frame buffering. Linear frame buffering simply means that the system's CPU is able to access every bit of the display. Historically, older graphic adapters could allow the CPU to access only 64K at a time, hence the limitations of the dreadful CGA/EGA graphic modes! It may be that someone will write a vesafb12 device driver for these cards, but this will use up precious kernel memory and involve a nasty hack.

There is however a potential workaround to add VESA 2.0 extensions for your legacy VESA 1.2 card. You may be able to download a TSR type program that will run from DOS, and used with loadlin, can help configure the card for the appropriate graphic console modes. Note that this will not always work, as an example some Cirrus Logic cards such as the VLB 54xx series are mapped to a range of memory addresses (for example, within the 15MB-16MB range) for frame buffering which preludes these from being used successfully with systems that have more than 32MB of memory. There is a way to make this work, i.e. if you have a BIOS option to leave a memory hole at 15MB-16MB range, it might work, Linux doesn't support the use of memory holes. However there are patches for this option though [Who has these and where do one gets them from?]. If you wish to experiment with this option, there are plenty of TSR style programs available, a prime example is UNIVBE, which can be found on the Internet.

Alternatively, you may be able to download kernel patches to allow your VESA 1.2 card to work with the VESA framebuffer driver. For example, there are patches for use with older S3 boards (such as S3 Trio, S3 Virge) that supports VESA 1.2. For these cards, you can pick up patches from ftp://ccssu.crimea.ua/pub/linux/kernel/v2.2/unofficial/s3new.diff.gz.

4.2. How do I activate the vesafb drivers?

Assuming you are using menuconfig, you will need to do the following steps:

If your processor (on x86 platforms) supports MTRRs, enable this. It speeds up memory copies between the processor and the graphic card, but not strictly necessary. You can of course, do this after you have the console device working.

IMPORTANT: For 2.1.x kernels, go into the Code Maturity Level menu, and enable the prompt for development and / or incomplete drivers. This is no longer necessary for the 2.2.x kernels.

Go into the Console Drivers menu, and enable the following:

VGA Chipset Support (text only) - vgafb - used to be part of the list above, but it has been removed as it is now deprecated and no longer supported. It will be removed shortly. Use VGA Text Console (fbcon) instead. VGA Character/Attributes is only used with VGA Chipset Support, and doesn't need to be selected.

Ensure that the Mac variable bpp packed pixel support is not enabled. Linux kernel release 2.1.111 (and 112) seemed to enable this automatically if Advanced Low Level Drivers was selected for the first time. This no longer happens with 2.1.113.

There is also the option to compile in fonts into memory, but this isn't really necessary, and you can always use kbd-0.99's (see section on fonts) setfont utility to change fonts by loading fonts into the console device.

Make sure these aren't going to be modules. [Not sure if it's possible to build them as modules yet - please correct me on this]

You'll need to create the framebuffer device in /dev. You need one per framebuffer device, so all you need to do is to type in mknod /dev/fb0 c 29 0 for the first one. Subsequent ones would be in multiples of 32, so for example to create /dev/fb1, you would need to type in mknod /dev/fb1 c 29 32, and so on up to the eighth framebuffer device (mknod /dev/fb7 c 29 224)

Then rebuild the kernel, modify /etc/lilo.conf to include the VGA=ASK parameter, and run lilo, this is required in order for you to be able to select the modes you wish to use.

Here's a sample LILO configuration (taken from my machine)

# LILO configuration file boot = /dev/hda3 delay = 30 prompt vga = ASK # Let user enter the desired modes image = /vmlinuz root = /dev/hda3 label = Linux read-only # Non-UMSDOS filesystems should be mounted read-only for checking

Reboot the kernel, and as a simple test, try entering 0301 at the VGA prompt (this will give you 640x480 @ 256), and you should be able to see a cute little Penguin logo.

Note, that at the VGA prompt, you're required to type in the number in the format of "0" plus the three-digit number, and miss out the 'x'. This isn't necessary if you're using LILO.

Once you can see that's working well, you can explore the various VESA modes (see below) and decide on the one that you like the best, and hardwire that into the "VGA=x" parameter in lilo.conf. When you have chosen the one you like the best, look up the equivalent hexadecimal number from the table below and use that (i.e. for 1280x1024 @ 256, you just use "VGA=0x307"), and re-run lilo. That's all there it is to it. For further references, read the LoadLin/LILO HOWTOs.

NOTE! vesafb does not enable scrollback buffering as a default. You will need to pass to the kernel the option to enable it. Use video=vesa:ypan or video=vesa:ywrap to activate it. Both does the same thing, but in different ways. ywrap is a lot faster than ypan but may not work on slightly broken VESA 2.0 graphic cards. ypan is slower than ywrap but a lot more compatible. This option is only present in kernel 2.1.116 and above. Earlier kernels did not have the ability to allow scrollback buffering in vesafb.

4.3. What VESA modes are available to me?

This really depends on the type of VESA 2.0 compliant graphic card that you have in your system, and the amount of video memory available. This is just a matter of testing which modes work best for your graphic card.

The following table shows the mode numbers you can input at the VGA prompt or for use with the LILO program. (actually these numbers are plus 0x200 to make it easier to refer to the table)

Table 1. VESA modes

Depth640x400640x480800x6001024x7681152x8641280x10241600x1200
4 bits??0x302????
8 bits0x3000x3010x3030x3050x1610x3070x31C
15 bits?0x3100x3130x3160x1620x3190x31D
16 bits?0x3110x3140x3170x1630x31A0x31E
24 bits?0x3120x3150x318?0x31B0x31F
32 bits????0x164??

Key: 8 bits = 256 colours, 15 bits = 32,768 colours, 16 bits = 65,536 colours, 24 bits = 16.8 million colours, 32 bits - same as 24 bits, but the extra 8 bits can be used for other things, and fits perfectly on a 32 bit PCI/VLB/EISA bus.

Additional modes are at the discretion of the manufacturer, as the VESA 2.0 document only defines modes up to 0x31F. You may need to do some fiddling around to find these extra modes.

4.4. Got a Matrox card?

If you've got a Matrox graphic card, you don't actually need vesafb, you need the matroxfb driver instead. This greatly enhances the capabilities of your card. Matroxfb will work with Matrox Mystique Millennium I & II, G100 and G200. It also supports multiheaded systems (that is, if you have two Matrox cards in your machine, you can use two displays on the same machine!). To configure for Matrox, you will need to do the following:

You might want to upgrade the Matrox BIOS first, you can download the BIOS upgrade from http://www.matrox.com/mgaweb/drivers/ftp_bios.htm Beware that you will need DOS to do this.

Go into the Code Maturity Level menu, and enable the prompt for development and/or incomplete drivers [note this may change for future kernels - when this happens, this HOWTO will be revised]

Go into the Console Drivers menu, and enable the following:

Rebuild your kernel. Then you will need to modify your lilo.conf file to enable the Matroxfb device. The quickest and simplest way is re-use mine.

# LILO configuration file boot = /dev/hda3 delay = 30 prompt vga = 792 # You need to do this so it boots up in a sane state # Linux bootable partition config begins image = /vmlinuz append = "video=matrox:vesa:440" # then switch to Matroxfb root = /dev/hda3 label = Linux read-only # Non-UMSDOS filesystems should be mounted read-only for checking

Lastly, you'll need to create the framebuffer device in /dev. You need one per framebuffer device, so all you need to do is to type in mknod /dev/fb0 c 29 0 for the first one. Subsequent ones would be in multiples of 32, so for example to create /dev/fb1, you would need to type in mknod /dev/fb1 c 29 32, and so on up to the eight framebuffer device (mknod /dev/fb7 c 29 224i)

And that should be it! [NOTE: Is anyone using this multiheaded support, please get in touch with me ASAP - I need to talk to you about it so I can document it!

4.5. Got a Permedia card?

Permedia cards cannot be used with the vesafb driver, but fortunately, there is the Permedia framebuffer driver available to use. Assuming you are using menuconfig, do the following:

Go into the Code Maturity Level menu, and enable the prompt for development and/or incomplete drivers [note this may change for future kernels - when this happens, this HOWTO will be revised]

Go into the Console Drivers menu and select the following:

Rebuild your kernel. Then you will need to modify your lilo.conf file to enable the pm2fb device. The quickest and simplest way is re-use the following:

# LILO configuration file boot = /dev/hda3 delay = 30 prompt vga = 792 # You need to do this so it boots up in a sane state # Linux bootable partition config begins image = /vmlinuz append = "video=pm2fb:mode:1024x768-75,font:SUN12x22,ypan" # then switch to pm2fb root = /dev/hda3 label = Linux read-only # Non-UMSDOS filesystems should be mounted read-only for checking

The line "pm2fb:mode:1024x768-75,font:SUN12x22,ypan" indicates you are selecting a 1024x768 mode at 75Hz, with the SUN12x22 font selected (if you did select it), including ypan for scrollback support. You may select other modes if you desire.

Lastly, you'll need to create the framebuffer device in /dev. You need one per framebuffer device, so all you need to do is to type in mknod /dev/fb0 c 29 0 for the first one. Subsequent ones would be in multiples of 32, so for example to create /dev/fb1, you would need to type in mknod /dev/fb1 c 29 32, and so on up to the eight framebuffer device (mknod /dev/fb7 c 29 224)

For more information on the other features of the Permedia framebuffer driver, point your browser at http://www.cs.unibo.it/~nardinoc/pm2fb/index.html

video=pm2fb:[option[,option[,option...]]]

where option is one of the following:

4.6. Got an ATI card?

[Note: This information is at best, only second-hand or third-hand, since I don't have an ATI card to test it with. Feel free to correct me if I am wrong or flame me!] 8)

ATI cards can be used with the vesafb driver, but you may or may not have problems, depending on how horribly broken the card is. Fortunately, there is the atyfb framebuffer driver available to use. Assuming you are using menuconfig, do the following:

Go into the Code Maturity Level menu, and enable the prompt for development and/or incomplete drivers [note this may change for future kernels - when this happens, this HOWTO will be revised]

Go into the Console Drivers menu and select the following:

Rebuild your kernel. Then you will need to modify your lilo.conf file to enable the atyfb device. The quickest and simplest way is re-use the following:

# LILO configuration file boot = /dev/hda3 delay = 30 prompt vga = 792 # You need to do this so it boots up in a sane state # Linux bootable partition config begins image = /vmlinuz append = "video=atyfb:mode:1024x768,font:SUN12x22" root = /dev/hda3 label = Linux read-only # Non-UMSDOS filesystems should be mounted read-only for checking

The line "atyfb:mode:1024x768,font:SUN12x22" indicates you are selecting a 1024x768 mode.

Lastly, you'll need to create the framebuffer device in /dev. You need one per framebuffer device, so all you need to do is to type in mknod /dev/fb0 c 29 0 for the first one. Subsequent ones would be in multiples of 32, so for example to create /dev/fb1, you would need to type in mknod /dev/fb1 c 29 32, and so on up to the eight framebuffer device (mknod /dev/fb7 c 29 224)

video=atyfb:[option[,option[,option...]]]

where option is one of the following:

4.7. Which graphic cards are VESA 2.0 compliant?

This lists all the graphic devices that are known to work with the vesafb device driver:

This list below blacklists graphic cards that doesn't work with the vesafb device:

4.8. Can I compile vesafb as a module?

As far as is known, vesafb can't be modularised, although at some point in time, the developer of vesafb may decide to modify the sources for modularising. Note that even if modularising is possible, at boot time you will not be able to see any output on the display until vesafb is modprobed. It's probably a lot wiser to leave it in the kernel, for these cases when there are booting problems.

4.9. How do I modify the cursor

With thanks to Martin Mares, taken from his VGA-softcursor.txt document.

Linux now has some ability to manipulate cursor appearance. Normally, you can set the size of hardware cursor (and also work around some ugly bugs in those miserable Trident cards -- see #define TRIDENT_GLITCH in drivers/char/vga.c). In case you enable "Software generated cursor" in the system configuration, you can play a few new tricks: you can make your cursor look like a non-blinking red block, make it inverse background of the character it's over or to highlight that character and still choose whether the original hardware cursor should remain visible or not. There may be other things I have never thought of.

The cursor appearance is controlled by a <ESC>[?1;2;3c escape sequence where 1, 2 and 3 are parameters described below. If you omit any of them, they will default to zeroes.

Parameter 1 specifies cursor size (0 = default, 1 = invisible, 2 = underline, ..., 8 = full block) + 16 if you want the software cursor to be applied + 32 if you want to always change the background colour + 64 if you dislike having the background the same as the foreground. Highlights are ignored for the last two flags.

The second parameter selects character attribute bits you want to change (by simply XORing them with the value of this parameter). On standard VGA, the high four bits specify background and the low four the foreground. In both groups, low three bits set colour (as in normal colour codes used by the console) and the most significant one turns on highlight (or sometimes blinking - it depends on the configuration of your VGA).

The third parameter consists of character attribute bits you want to set. Bit setting takes place before bit toggling, so you can simply clear a bit by including it in both the set mask and the toggle mask.