本文转自 http://blogold.chinaunix.net/u2/70445/showart_2098725.html
帧缓冲设备属于字符设备,采用了 “ 文件层-驱动层 ” 的接口方式。 Linux 为帧缓冲设备定义的驱动层接口为 struct fb_info 结构。在文件层次上, Linux 为其定义了下面的操作函数: struct file_operations
软件运行流程 :
在文件层次上 , 用户调用 struct file_operations 的函数操作 , 在 struct file_operations 中间接调用 struct fb_ops 的函数来操作硬件 . 当向内核注册 FB 设备的时候 , 也注册了 struct fb_ops 的指针 . 当打开 fb 设备时 , 先调用 fb_drivers[] 的 xxxfb_init() 来初始化设备 ;
1 、开发步骤和框架
涉及的文件: fb.h, fbmem.c, xxxfb.c.
fb.h: 定义了一些结构 , 变量和宏 ;
fbmem.c: 主要实现设备入口和初始化 , 如 struct file_operations;
入口点 :
static struct {
const char *name;
int (*init)(void);
int (*setup)(char*);
} fb_drivers[] __initdata = {
#ifdef CONFIG_FB_YOURCARD
{ "driver_name", xxxfb_init, xxxfb_setup },
#endif
文件操作 :
static struct file_operations fb_fops = {
owner: THIS_MODULE,
read: fb_read,
write: fb_write,
ioctl: fb_ioctl,
mmap: fb_mmap,
open: fb_open,
release: fb_release,
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
get_unmapped_area: get_fb_unmapped_area,
#endif
};
xxxfb.c: 自己添加的设备驱动文件 , 如 struct fb_info;
实现入口点函数 : xxxfb_init; xxxfb_setup;
static struct fb_ops xxxfb_ops = {
owner: THIS_MODULE,
fb_open: xxxfb_open, /* only if you need it to do something */
fb_release: xxxfb_release, /* only if you need it to do something */
fb_get_fix: fbgen_get_fix,
fb_get_var: fbgen_get_var,
fb_set_var: fbgen_set_var,
fb_get_cmap: fbgen_get_cmap,
fb_set_cmap: fbgen_set_cmap,
fb_pan_display: fbgen_pan_display,
fb_ioctl: xxxfb_ioctl, /* optional */
};
2 、什么是 framebuffer 设备
framebuffer 是一种能够提取图形的硬件设备,是用户进入图形界面很好的接口。有了 framebuffer ,用户的应用程序不需要对底层的驱动的深入了解就能够做出很好的图形。
对于用户而言,它和 /dev 下面的其他设备没有什么区别,用户可以把
framebuffer 看成一块内存,既可以向这块内存中写入数据,也可以从这块内存中读取数据。
第一个被注册的 framebuffer 的 minor 等于 0 ,第二个被注册的 framebuffer 的 minor 等于 1 ,以此类推。
3 、 framebuffer 内部结构
数据结构: framebuffer 设备很大程度上依靠了下面四个数据结构。这三个结构在 fb.h 中声明。
Struct fb_var_screeninfo
Struct fb_fix_screeninfo
Struct fb_info
第一个结构是用来描述图形卡的特性的。通常是被用户设置的。它包括显示屏幕的分辨率、每个像素的比 特数和一些时序变量。其中变量 xres 定义了屏幕一行所占的像素数, yres 定义了屏幕一列所占的 像素数, bits_per_pixel 定义了每个像素用多少个位来表示。
第二个结构定义了图形卡的硬件特性,是不能改变的,用户选定了哪一个图形卡,那么它的硬件特性也就 定下来了。它包含了屏幕缓冲区的物理地址和长度。
第三个结构是 Linux 为帧缓冲设备定义的驱动层接口。它不仅包含了底层函数,而且还有记录设备状态的 数据。每个帧缓冲设备都与一 fb_info 结构相对应。其中成员变量 modename 为设备名称, fontname 为显示字体, fbops 为指向底层操作的函数的指针。定义了当前图形卡 framebuffer 设 备的独立状态,一个图形卡可能有两个 framebuffer , 在这种情况下,就需要两个 fb_info 结构 。这个结构是唯一在内核空间可见的。
4 、设计自己的 framebuffer 设备驱动
用户首先需要添加下面的代码到 fbmem.c
static struct {
const char *name;
int (*init)(void);
int (*setup)(char*);
} fb_drivers[] __initdata = {
#ifdef CONFIG_FB_YOURCARD
{ "driver_name", xxxfb_init, xxxfb_setup },
#endif
其次在 xxfb.c 中根据自己的需要重新分配显存大小。例如:
#define VIDEOMEMSIZE (1*1024*1024) /* 1 MB */
再次根据自己的硬件设备修改相应的 var 信息。主要修改
xxfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) 函数。
5 、如何添加 framebuffer 设备驱动
在 make menuconfig 的时候首先进入 Character devices, 选中里面的 Virtualterminal. 如果希望控制台在液晶上输出,则选中 Support for console on virtual terminal 。 ( 选用了 msh ( minix shell ) , 再在 rc 中放入了一条 sh < /dev/ttyS0 ,通过串口输入的键值显示输出就能在 LCD 上显示了。)
退到上一层界面我们就可以看到 Console device 的选项,进入后将光标落在 Framebuffer Support 上,按回车键进入,在里面选择自己所需要的 framebuffer 设备即可。自己所添加的设备驱动的类型(如果在 uclinux 下,应该以 * 选中,而不是 M 选中),在编译的时候就会产生相应的 .o 文件。
在 Advanced low level 中可以配置 bpp packed pixel support, 然后选中 Selectcompiled-in fonts 即可。
等操作系统运行以后就会在 /dev 下面看到 fb 这个设备。它的 major 应该是 29 ,第一个设备的 minor 应该是 0 。