framebuffer的探讨

1.ramebuffer基础知识

Linux2.2以上的版本中使用了framebuffer技术,这使得用户对显示设备进行写入、控制时可以避免对内存映射区进行操作,因此用户可以在不了解底层图形硬件或没有使用过X Window的情况下进行图形程序的开发。framebuffer是一种驱动程序接口用户需要编译内核来实现对framebuffer的支持framebuffer的设备为/dev/fb0/dev/fb1等。对Linux来讲周边都被视为一种文件设备来代表,放在/dev目录下,fb表示一种周边代号。

应用程序通过使用mmap()系统调用将显存映射到用户空间来实现对显存的直接操作。使用framebuffer主要会用到下面几个内核空间中的文件:(以RedHat9.0为例)

/usr/src/linux-2.4.20-8/include/linux/fb.h

/usr/src/linux-2.4.20-8/drivers/video/fbmem.c

/usr/src/linux-2.4.20-8/drivers/video/fbcmap.c

fb.h中定义了几个重要的结构体,fb_info fb_fix_screeninfofb_var_screeninfofb_cmap等。在fbmem.c中则定义了对framebuffer的操作部分,诸如fb_readfb_writefb_ioctlfb_mmapfb_openfb_release等,同时还在其中定义了一个fb_fops结构来实现这些操作:

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

};

有关函数的具体定义可以参考阅读fbmem.c文件。fbcmap.c文件实现了对colormap的处理,其中包括如fb_alloc_cmap等函数。

下面我们来通过一个简单的例子来加深对framebuffer的理解,我们可以通过ioctl函数

来获得framebuffer的信息。

if (ioctl(fb, FBIOGET_VSCREENINFO, &fb_vinfo))

{    

printf("Can't get VSCREENINFO: %s\n"strerror(errno));  

       close(fb);

return -1;

}

if (ioctl(fb, FBIOGET_FSCREENINFO, &fb_finfo))

{    

printf("Can't get FSCREENINFO: %s\n", strerror(errno));

return 1;

}

fbdev.fb_bpp = fb_vinfo.red.length + fb_vinfo.green.length

+ fb_vinfo.blue.length + fb_vinfo.transp.length;

fbdev.fb_width = fb_vinfo.xres;

fbdev.fb_height = fb_vinfo.yres;

fbdev.fb_line_len = fb_finfo.line_length;

fbdev.fb_size = fb_finfo.smem_len;

printf("frame buffer: %dx%d, %dbpp, 0x%xbyte\n", fbdev.fb_width, fbdev.fb_height, fbdev.fb_bpp,       fbdev.fb_size);

在上面的代码中通过ioctl得到了framebuffer设备的分辨率、色深和显存大小,当然我们还可以得到其它信息。接下来使用mmap()调用,实现显示缓冲到用户空间。

fbdev.fb_mem=mmap(NULL,fbdev.fb_size,PROT_READ|PROT_WRITE,MAP_SHARED,

fb,0);

if(fbdev.fb_mem==NULL || (int)fbdev.fb_mem==-1)

{    

       fbdev.fb_mem=NULL;

       printf("mmap failed\n");             

close(fb);       

return -1;

}

       memset (fbdev.fb_mem, 0x0, fbdev.fb_size);

上面的fbdev.fb_mem是映射到用户空间的显存的起始地址,关于mmapmemset的详细使用可以使用man来查看手册。

对于bpp(色深)为8位或8位以下的设备,在进行绘图前需要对调色板进行设置,有关调色板的结构fb_cmap的结构定义在fb.h中,有关调色板的设置需要修改fbcmap.c


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值