Playing with linux framebuffer

Published 12-19-2012 00:00:00

What is framebuffer ?

The Linux framebuffer is an abstraction layer, hardware independant, to display graphical elements in Linux console. Framebuffer is often used in embedded devices. Thanks to DirectFB, hadware acceleration can be used.

How to program framebuffer ?

Programming the Linux framebuffer is quite simple:

  • ioctl commands and structs are located in /usr/include/linux/fb.h
  • use open(2) to open /dev/fb0
  • use various ioctl(2) calls to get or set properties
  • mmap(2) framebuffer device to memory
  • write to the mmaped memory to display your graphics

Usefull structs are:

struct fb_var_screeninfo; /* Get variable screen informations with FBIOGET_VSCREENINFO */
struct fb_fix_screeninfo; /* Get fixed screen informations with FBIOGET_FSCREENINFO */

A simple program

Return codes are not checked for simplicity.

Includes:

#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/fb.h>

First, open the framebuffer device,

int fbfd;
fbfd = open("/dev/fb0", O_RDWR);

Get various screen informations with ioctl,

static struct fb_fix_screeninfo finfo;
static struct fb_var_screeninfo vinfo;

ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo);
ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo);

fprintf(stdout, "Fixed screen informations\n"
                "-------------------------\n"
                "Id string: %s\n"
                "FB start memory: %p\n",
                finfo.id, (void *)finfo.smem_start);

fprintf(stdout, "Variable screen informations\n"
                "----------------------------\n"
                "xres: %d\n"
                "yres: %d\n"
                "xres_virtual: %d\n"
                "yres_virtual: %d\n"
                "bits_per_pixel: %d\n",
                vinfo.xres, vinfo.yres, vinfo.xres_virtual,
                vinfo.yres_virtual, vinfo.bits_per_pixel);

Mmap framebuffer device,

screen_size = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
fbp = mmap(NULL, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);

Yon can now draw a green rectangle in console mode

int x = 20; int y = 20; /* Upper left corner */
int w = 40; int h = 60; /* Width and height */

for (int j = 0; j < h; ++j) {
    for (int i = 0; i < w; ++i) {
        unsigned char *p;

        p = fbp + ((y + j) * vinfo.xres + (x + i)) * vinfo.bits_per_pixel/8;

        /* We consider a 32 bits per pixels */
        p[0] = 0;   /* blue */
        p[1] = 255; /* green */
        p[2] = 0;   /* red */
        p[3] = 0;   /* alpha */
    }
}

Do not forget to release allocated resources,

munmap(fbp, 0);
close(fbfd);