概念:
1、像素:pixel,点阵,就是屏幕上的一个点。
2、Bpp:每个像素所占的bit数。bit数越大,一个像素能表现颜色数越多。8bpp,能表现256种颜色。16Bpp能表现65536种颜色。
3、分辨率:一个屏幕x方向和y方向所能排列的像素数。比如240*320,240代表x方向的像素个数,320代表y方向的像素个数,整个屏幕所能占有的像素个数
为240*320=76800。
4、 Frame buffer:帧缓冲区,显示一帧所占的内存存储空间,可以认为是显存。帧缓冲区的内容和屏幕上的点空间一般是行对应的。每行存储着这行的每个像素的颜色信
息,像素的信息大小由bpp决定。
5、Console:控制台,指可以显示内核信息,并且允许用户登录的设备。
6、terminal:终端,指有显示器或者LCD作为输出,键盘作为输入的设备。
7、Virtual terminal:虚拟终端,简称VT。指在一个标准终端可以虚拟多个终端设备。在PC上,各个虚拟终端可以用ALT+功能键切换。
重要数据结构:
在include/linux/fb.h中定义:
struct fb_fix_screeninfo:描述framebuffer设备在使用过程中,固定不变的一些属性。用户和内核空间可见。
struct fb_var_screeninfo:描述framebuffer设备在之用过程中,需要改变或设定的一些属性。用户和内核空间可见。
struct fb_ops:framebuffer设备的一些操作函数。只在内核空间可见。
struct fb_info:描述一个framebuffer设备。上面三个嵌入在这个结构中。只在内核空间可见。
struct fb_fix_screeninfo介绍:
id:字符串表示的字符标识。
smem_start:framebuffer使用的内存起始地址,表示的是物理地址。
smem_line:framebuffer所占用的内存的大小,字节为单位。
type:Framebuffer的类型。多用FB_TYPE_PACKED_PIXELS_。
visual:表示可见颜色。4,8bpp用FB_VISUAL_PSEUDOCOLOR和FB_VISUAL_STATIC_PSEUDOCOLOR;16,24,32使用FB_VISUAL_TRUCOLOR。
line_length:一行所占内存的长度,以字节为单位。
accel:是否使用硬件加速,一般为FB_ACCEL_NONE,表示没有使用。
struct fb_var_screeninfo介绍:
xres,yres:x,y方向的可见分辨率。表示可以看见的屏幕大小。
xres_virtual,yres_virtual:x和y方向的虚拟分辨率。表示可以显示的屏幕大小。
xoffset,yoffset:x和y方向的可见分辨率和虚拟分辨率的偏移。
bits_perl_pixel:bpp,每个点阵或者象素所占bit数。
struct fb_ops介绍:
fb_get_fix:获取struct fb_fix_screeninfo结构
fb_get_var:获取struct fb_var_screeninfo结构
fb_set_var:设置struct fb_var_screeninfo
struct fb_info结构介绍:
char modename[40]:framebuffer设备名称。在/proc/fb可查看。
Struct fb_var_screeninfo var
srtuct fb_fix_screeninfo fix
struct fb_ops *fbops
char *screen_base:虚拟地址
char fontname[40]:使用的字体名字。
(2)编写驱动程序
xxxfb_setup:解析命令行参数
在video_setup(driver/video/fmem.c)中调用。解析类似video=xxx:opt1,opt2的命令行参数。
xxxfb_init:驱动程序初始化函数
xxxfb_init_fbinfo:初始化xxxfb_info结构。
xxxfb_map_video_memory:分配系统内存给显示设备。
xxxfb_hw_init:初始化显示硬件
xxxfb_set_var:设定参数,根据xxxfb_init_fbinfo初始化的参数设备fb_var_screeninfo。
register_framebuffer:注册fb_info结构,成为framebuffer设备
实现xxxfb_ops结构和它的函数。
Framebuffer应用程序编程
打开framebuffer设备
int fd = open(“/dev/fb0”, O_RDWR);
关闭framebuffer设备
close(fd);
读取framebuffer信息
struct fb_fix_screeninfo fb_fix;
struct fb_var_screeninfo fb_var;
if(ioctl(fd, FBIOGET_FSCREENINFO, &fb_fix) == -1 || ioctl(fd, FBIOGET_VSCEERNINFO, &fb_var) == -1)
{
printf(“Error reading screen info:\n”);
}
设置framebuffer设备信息
ioctl(fd, FBIOPUT_VSCREENINFO, &fb_var);
读写设备文件
lseek定位要写的点
write写相应的值到此点
read读相应的点
映射显示区域到应用程序空间
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
addr,映射起始地址。0表示由系统指定地址。
Length, 映射空间长度。为framebuffer所占显示内存空间大小。
prot:内存保护标志,表示读写和执行权限。PROT_READ和PROT_WRITE,表示可读可写。
Flags, 标志位。使用MAP_SHARED表示写内存就同时写入文件中。
Fd, 要映射的文件句柄。
offset:要映射的文件的起始偏移。
解决/dev/fb0无法打开的问题?
最近要在Linux做基于frame Buffer的图形显示,在装有Red hat5的linux中,都无法打开/dev/fb0.也就是dev/目录下无fb0.
1、首先确认对Frame Buffer的支持是否编译到Linux的内核中。在安装的Linux中,默认都会把这个支持打开编译到内核中。但是如果自己重新编译了内核,或者升级内核,得确认
把Frame Buffer的支持编入内核,并且还要把Console display driver support编译到内核中,还要把Logo configuration编译到内核中。这些选项都在Device drivers下
的graphics support选项下。
2、在启动项中打开对Frame Buffer的支持。由于虽然把对Frame Buffer的支持编译到内核中了,但是默认下是没有打开的。故要修改/boot/grub/menu.lst文件。在该文件的kernel那一
行后面加上vga=0xXXX,0xXXX表示的是屏幕的分辨率和色彩数。
其中vga=0x后面的数值可以从下表中查出。(我用0x317)
色彩数 640 X 480 800X600 1024X768 1280X1024
256 0x301 0x303 0x305 0x307
32k 0x310 0x313 0x316 0x319
64k 0x311 0x314 0x317 0x31A
16M 0x312 0x315 0x318 0x31B
# vim /boot/grub/menu.lst
修改后,如下:
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=/dev/hda3
# initrd /initrd-version.img
#boot=/dev/hda
default=0
timeout=10
splashimage=(hd0,0)/grub/splash.xpm.gz
title Red Hat Linux (2.6.18)
root (hd0,0)
kernel /vmlinuz-2.6.18 ro root=LABEL=/ vga=0x317
initrd /initrd-2.6.18.img
3、重启系统,Console启动会有一只企鹅在屏幕上方显示。然后运行cat /dev/fb0,如果发现有一堆乱码输出在屏幕上,则表示找到了/dev/fb0这个设备。如果没有,则可能
是你的显卡不支持。