Chinaunix首页 | 论坛 | 博客
  • 博客访问: 111972
  • 博文数量: 95
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 12
  • 用 户 组: 普通用户
  • 注册时间: 2013-04-27 08:43
文章分类
文章存档

2013年(95)

我的朋友

分类: LINUX

2013-04-27 08:58:54

原文地址:FrameBuffer研究 作者:soararing

一.使用基础

  1. Linux是工作在保护模式下,所以用户态进程是无法象DOS那样使用显卡BIOS里提供的中断调用来实现直接写屏,Linux抽象出FrameBuffer这个设备来供用户态进程实现直接写屏。对于用户而言,framebuffer和/dev下面的其他设备没有什么区别,用户可以把framebuffer 看成一块内存,既可以向这块内存中写入数据,也可以从这块内存中读取数据。在应用程序中,一般通过将 FrameBuffer 设备映射到进程地址空间的方式使用。

2.在这种机制下,尽管Framebuffer需要真正的显卡驱动的支持,但所有显示任务都有CPU完成,因此CPU负担很重.

3.PCI 设备可以将自己的控制寄存器映射到物理内存空间,而后,对这些控制寄存器的访问,给变成了对物理内存的访问。因此,这些寄存器又被称为"memio"。一旦被映射到物理内存,Linux 的普通进程就可以通过 mmap 将这些内存 I/O 映射到进程地址空间,这样就可以直接访问这些寄存器了。

4.帧缓冲设备属于字符设备,采用了文件层-驱动层的接口方式。Linux为帧缓冲设备定义的驱动层接口为struct fb_info结构。在文件层次上,用户调用struct file_operations的函数操作,其中间接调用struct fb_ops的函数来操作硬件.当向内核注册FB设备的时候,也注册了struct fb_ops的指针.当打开fb设备时,先调用fb_drivers[]xxxfb_init()来初始化设备;

5.第一个被注册的framebuffer的minor等于0,第二个被注册的framebuffer的minor等于1,以此类推。如/dev/fb0,/dev/fb1。

 

 

可以用命令: #dd if=/dev/zero of=/dev/fb 清空屏幕.
如果显示模式是 1024x768-8 位色,用命令:$ dd if=/dev/zero of=/dev/fb0 bs=1024 count=768 清空屏幕
用命令: #dd if=/dev/fb of=fbfile  可以将fb中的内容保存下来;
可以重新写回屏幕: #dd if=fbfile of=/dev/fb
二.  framebuffer内部结构
Framebuffer对应的源文件在linux/drivers/video/目录下。总的抽象设备文件为fbcon.c,在这个目录下还有与各种显卡驱动相关的源文件。FrameBuffer设备驱动基于如下文件:
1) linux/include/linux/fb.h定义一些变量结构和宏。
2) linux/drivers/video/fbmem.c实现设备入口和初始化。
3)xxxfb.c: 自己添加的设备驱动文件,如struct fb_info;实现入口点函数: xxxfb_init; xxxfb_setup;
        1.首先是fb.hframebuffer设备很大程度上依靠了下面数据结构。
1).Struct fb_var_screeninfo描述图形卡的特性的。通常是被用户设置的。
2).Struct fb_fix_screeninfo定义了图形卡的硬件特性,是不能改变的。
3).Struct fb_cmap描述设备无关的颜色映射信息。可以通过FBIOGETCMAP和FBIOPUTCMAP 对应的ioctl操作设定或获取颜色映射信息.
4).Struct fb_info定义了当前图形卡framebuffer设备状态,一个图形卡可能有两个framebuffer,在这种情况下,就需要两个fb_info结构。这个结构是唯一在内核空间可见的。在这个结构中有一个fb_ops指针,指向驱动设备工作所需的函数集。
5).struct fb_ops用户应用可以使用ioctl()系统调用来操作设备,这个结构就是用以支持ioctl()的这些操作的。(注: fb_ops结构与file_operations 结构不同,fb_ops是底层操作的抽象,而file_operations是提供给上层系统调用的接口,可以直接调用.)ioctl()系统调用在文件fbmem.c中实现,通过观察可以发现ioctl()命令与fb_ops’s 中函数的关系:
FBIOGET_VSCREENINFO fb_get_var
FBIOPUT_VSCREENINFO fb_set_var
FBIOGET_FSCREENINFO fb_get_fix
FBIOPUTCMAP fb_set_cmap
FBIOGETCMAP fb_get_cmap
FBIOPAN_DISPLAY fb_pan_display
如果我们定义了fb_XXX_XXX 方法,用户程序就可以使用FBIOXXXX宏的ioctl()操作来操作硬件。
2.其次是fbmem.cfbmem.c 处于Framebuffer设备驱动技术的中心位置.它为上层应用程序提供系统调用也为下一层的特定硬件驱动提供接口;那些底层硬件驱动需要用到这儿的接口来向系统内核注册它们自己. fbmem.c 为所有支持FrameBuffer的设备驱动提供了通用的接口.
1) 全局变量
struct fb_info *registered_fb[FB_MAX];
int num_registered_fb;
这两变量记录了所有fb_info 结构的实例,fb_info 结构描述显卡的当前状态,所有设备对应的fb_info 结构都保存在这个数组中,当一个FrameBuffer设备驱动向系统注册自己时,其对应的fb_info 结构就会添加到这个结构中,同时num_registered_fb 为自动加1.
2)fbmem.c 实现了如下函数.
register_framebuffer(struct fb_info *fb_info);
unregister_framebuffer(struct fb_info *fb_info);
这两个是提供给下层FrameBuffer设备驱动的接口,设备驱动通过这两函数向系统注册或注销自己。几乎底层设备驱动所要做的所有事情就是填充fb_info结构然后向系统注册或注销它。
        3.xxxfb.c自己添加的设备驱动文件,如以下等内容。
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 */
};
 
三framebuffer驱动。
1.首先需要添加下面的代码到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
2.其次在xxxfb.c 中根据自己的需要重新分配显存大小。例如:
 #define VIDEOMEMSIZE (1*1024*1024) /* 1 MB */
再次根据自己的硬件设备修改相应的var 信息。主要修改
xxxfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
      下面是函数fb_set_var()的执行步骤:
1)检测是否必须设定模式
2)设定模式
3)设定颜色映射
4) 根据以前的设定重新设置LCD控制器的各寄存器。
四.配置添加驱动
1.make menuconfig时,首先进入Character devices,选中里面的Virtualterminal.如果希望控制台在液晶上输出,则选中Support for console on virtual terminal
2.退到上一层界面我们就可以看到Console device 的选项,进入后将光标落在Framebuffer Support 上,按回车键进入,在里面选择自己所需要的framebuffer设备即可。
3.Advanced low level 中可以配置bpp packed pixel support,然后选中Selectcompiled-in fonts 即可。
等操作系统运行以后就会在/dev下面看到fb 这个设备。它的major应该是29,第一个设备的minor应该是0
.其它
编译内核时,选择framebuffer模式,启动时屏幕上有一企鹅图片,不知这是如何造成的这个图片可以去掉或改动吗?
答:可以将drivers/video/fbcon.c: fbcon_setup()if (logo) { } 代码去掉。
阅读(560) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~