Linux源代碼包中/document/fb/framebuffer.txt有例如以下介紹:
The frame buffer device provides an abstraction for the graphics hardware. It represents the frame buffer of some video hardware and allows application software to access the graphics hardware through a well-defined interface, so the software doesn't need to know anything about the low-level (hardware register) stuff.Frame buffer機制為圖形顯示卡提供了一個抽象層。
能夠使得應用程序不用考慮底層硬件的實現細節而通過一些API接口就可以訪問到顯示設備。 但Framebuffer本身不具備不論什么運算數據的能力,就僅僅好比是一個臨時存放水的水池。水池里的水就是顯示的東西。CPU將運算后的結果放到這個水池,水池再將結果流到顯示器(通常通過DMA傳輸). 所以應用程序通過讀寫這個水池。就可以相當於操作了顯示卡。系統中能夠在/dev/fb*看到framebuffer設備。
以下這幅圖非常好的描寫敘述了framebuffer執行機制:

framebuffer子系統的層次結構:

上圖主要在以下文件里:
drivers/vedio/fbmem.c 該文件是framebuffer實現的核心。與硬件無關
drivers/vedio/xxxfb.c 該文件主要是framebuffer 設備驅動的實現,如s3c2410fb.c實現了framebuffer設備驅動
fbmem.c是實現framebuffer的核心。與硬件無關。
它使用了以下這些數據結構:
struct fb_info *fb_info 該數據結構描寫敘述了一個framebuffer device相關一系列信息struct fb_ops *fb_ops 該數據結構描寫敘述了一個framebuffer device的操作函數集合。相似file_operations,但僅僅供內核使用
static const struct file_operations fb_fops 該數據結構為文件操作函數集合。當應用程序打開設備時。用戶能夠read,write,ioctl等
struct fb_var_screeninfo var 該數據結構描寫敘述了framebuffer device顯示特性,是能夠更改的
struct fb_fix_screeninfo fix 該數據結構用於保存framebuffer device顯示特性,是固定不變的,不能夠更改
詳細數據結構:
framebuffer設備的注冊與注銷:
register_framebuffer(struct fb_info *fb_info);
unregister_framebuffer(struct fb_info *fb_info);
以下看看fb_ioctl 都做了什么?
static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
unsigned long arg)
{
struct fb_ops *fb;
struct fb_var_screeninfo var;
struct fb_fix_screeninfo fix;
struct fb_con2fbmap con2fb;
struct fb_cmap cmap_from;
struct fb_cmap_user cmap;
struct fb_event event;
void __user *argp = (void __user *)arg;
long ret = 0;
switch (cmd) {
case FBIOGET_VSCREENINFO:
if (!lock_fb_info(info))
return -ENODEV;
var = info->var;
unlock_fb_info(info);
ret = copy_to_user(argp, &var, sizeof(var)) ? -EFAULT : 0;
break;
case FBIOPUT_VSCREENINFO:
if (copy_from_user(&var, argp, sizeof(var)))
return -EFAULT;
if (!lock_fb_info(info))
return -ENODEV;
console_lock();
info->flags |= FBINFO_MISC_USEREVENT;
ret = fb_set_var(info, &var);
info->flags &= ~FBINFO_MISC_USEREVENT;
console_unlock();
unlock_fb_info(info);
if (!ret && copy_to_user(argp, &var, sizeof(var)))
ret = -EFAULT;
break;
case FBIOGET_FSCREENINFO:
if (!lock_fb_info(info))
return -ENODEV;
fix = info->fix;
unlock_fb_info(info);
ret = copy_to_user(argp, &fix, sizeof(fix)) ? -EFAULT : 0;
break;
case FBIOPUTCMAP:
if (copy_from_user(&cmap, argp, sizeof(cmap)))
return -EFAULT;
ret = fb_set_user_cmap(&cmap, info);
break;
case FBIOGETCMAP:
if (copy_from_user(&cmap, argp, sizeof(cmap)))
return -EFAULT;
if (!lock_fb_info(info))
return -ENODEV;
cmap_from = info->cmap;
unlock_fb_info(info);
ret = fb_cmap_to_user(&cmap_from, &cmap);
break;
case FBIOPAN_DISPLAY:
if (copy_from_user(&var, argp, sizeof(var)))
return -EFAULT;
if (!lock_fb_info(info))
return -ENODEV;
console_lock();
ret = fb_pan_display(info, &var);
console_unlock();
unlock_fb_info(info);
if (ret == 0 && copy_to_user(argp, &var, sizeof(var)))
return -EFAULT;
break;
case FBIO_CURSOR:
ret = -EINVAL;
break;
case FBIOGET_CON2FBMAP:
if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
return -EFAULT;
if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
return -EINVAL;
con2fb.framebuffer = -1;
event.data = &con2fb;
if (!lock_fb_info(info))
return -ENODEV;
event.info = info;
fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event);
unlock_fb_info(info);
ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0;
break;
case FBIOPUT_CON2FBMAP:
if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
return -EFAULT;
if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
return -EINVAL;
if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
return -EINVAL;
if (!registered_fb[con2fb.framebuffer])
request_module("fb%d", con2fb.framebuffer);
if (!registered_fb[con2fb.framebuffer]) {
ret = -EINVAL;
break;
}
event.data = &con2fb;
if (!lock_fb_info(info))
return -ENODEV;
event.info = info;
ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event);
unlock_fb_info(info);
break;
case FBIOBLANK:
if (!lock_fb_info(info))
return -ENODEV;
console_lock();
info->flags |= FBINFO_MISC_USEREVENT;
ret = fb_blank(info, arg);
info->flags &= ~FBINFO_MISC_USEREVENT;
console_unlock();
unlock_fb_info(info);
break;
default:
if (!lock_fb_info(info))
return -ENODEV;
fb = info->fbops;
if (fb->fb_ioctl)
ret = fb->fb_ioctl(info, cmd, arg);
else
ret = -ENOTTY;
unlock_fb_info(info);
}
return ret;
}
static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct fb_info *info = file_fb_info(file);
printk(\nfb_ioctl mem\n);
if (!info)
return -ENODEV;
return do_fb_ioctl(info, cmd, arg);
}
依據文件操作的static const struct file_operations fb_fops,應用程序在打開一個framebuffer設備時。能夠使用read,write,ioctl來直接操作設備。
應用例程:

