Chinaunix首页 | 论坛 | 博客
  • 博客访问: 146387
  • 博文数量: 54
  • 博客积分: 2517
  • 博客等级: 少校
  • 技术积分: 540
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-13 18:52
文章分类
文章存档

2011年(2)

2010年(11)

2009年(41)

我的朋友

分类: LINUX

2009-09-16 21:32:31

framebuffer相关知识总结

Vesafb介绍

VESAVideo Electronic Standards Association影像电子工程标准协会的缩,由多家计算机芯片制造商于1989年联合创立,1994年底,VESA发表了64位架构的VESA Local Bus标准,80486以后的PC机大多采用这一标准的显卡。

Vesafb is a framebuffer driver for Intel architecture that works with VESA 2.0 compliant graphic cards

Linear frame buffering simply means that the system's CPU is able to access every bit of the display.

 

显卡简介

显示适配卡Video cardGraphics card),又称为显示适配器video adapter),简称为显卡显示卡简称为显示卡,是最基本组成部分之一。-{A|zh-cn:显卡;zh-tw:显示卡}-的用途是将计算机系统所需要的显示信息进行转换驱动,并向显示器提供行扫描信号,控制显示器的正确显示,是联接显示器和个人电脑主板的重要组件,是人机对话的重要设备之一。

显卡是插在主板上的扩展槽里的(现在一般是插槽)。它主要负责把主机向显示器发出的显示信号转化为一般电信号,使得显示器能明白个人电脑在让它干什么。显卡的主要芯片叫Video chipset,也叫,图形处理器或视觉处理器),是显卡的主要处理单元。显卡上也有和电脑内存相似的存储器,称为显示内存,简称

早期的显卡只是单纯意义的显卡,只起到信号转换的作用;目前我们一般使用的显卡都带有3D画面运算和图形加速功能,所以也叫做图形加速卡

显卡通常由总线接口、板、显示芯片、显存、RAMDACVGA BIOSVGA功能插针、VGA插座及其它外围组件构成,现在的显卡大多还具有显示器插头及端子插头。

ISA显卡

ISA显卡是现在最普遍使用的VGA显示器所能支持的最为古老的显卡。

VESA显卡

VESAVideo Electronic Standards Association影像电子工程标准协会的缩写,由多家计算机芯片制造商于联合创立,底,VESA发表了64位架构的VESA Local Bus标准,80486以后的PC机大多采用这一标准的显卡。

PCI显卡

显卡

AGP(Accelerated Graphics Port)Intel公司在开发的32位总线接口,用来增进计算机系统中的显示效能。分有AGP 1X , AGP 2X ,AGP 4X 及最后的AGP 8X , 频宽分别为 266MB/s ,533MB/s ,1066MB/2133 MB/s。其中 AGP 4X 以后已跟之前电压不兼容。性能最好的AGP显示卡是公司的 6800 Ultra 公司的 X850 XT PE

显卡

PCI Express是显示卡最新的图形接口,用来取代AGP显示卡的,因为面对日后3D显示技术的不断进步,的宽带已经不能再满足庞大的数据运算。目前性能最高的PCI-Express显示卡是公司的GeForce 7800GTX 512MB公司的X1900XTX。此外, 现时部分显示卡可-{zh-tw:支援;zh-cn:支持}-双显示卡(). 当中, 大部分都需要一张子卡和一张主卡去运行, X1300就无此限制,而此限制也即将解封。

 

MTRR含义

MTRR (Memory Type Range Register) support (CONFIG_MTRR) [N/y/?]

选择该选项,系统将生成/proc/mtrr文件对MTRR进行管理,供X server使用。

Intel p6家族的处理器中(Ppro PII和更新的)有一个内存类型范围寄存器,可用来控制处理器访问的内存范围。打开它一般可以提升显卡的显示性能

It speeds up memory copies between the processor and the graphic card

linux framebuffer相关

 

又学习到结构体初始化定义的一个绝招,具体如下:
结构体定义(见/include/linux/fb.h

struct fb_fix_screeninfo {

       char id[16];                  /* identification string eg "TT Builtin" */

       unsigned long smem_start;    /* Start of frame buffer mem */

                                   /* (physical address) */

       __u32 smem_len;                 /* Length of frame buffer mem */

       __u32 type;                  /* see FB_TYPE_*        */

       __u32 type_aux;                   /* Interleave for interleaved Planes */

       __u32 visual;                /* see FB_VISUAL_*            */

       __u16 xpanstep;                   /* zero if no hardware panning  */

       __u16 ypanstep;                   /* zero if no hardware panning  */

       __u16 ywrapstep;          /* zero if no hardware ywrap    */

       __u32 line_length;         /* length of a line in bytes    */

       unsigned long mmio_start;     /* Start of Memory Mapped I/O   */

                                   /* (physical address) */

       __u32 mmio_len;                  /* Length of Memory Mapped I/O  */

       __u32 accel;                 /* Type of acceleration available */

       __u16 reserved[3];        /* Reserved for future compatibility */

};

/drivers/video/Anakinfb.c

结构体初始化,注意并不是初始化全部成员变量,而是一部分,这是一种简捷的定义方式,注意每个成员变量前有一个“.”号,你有更好的定义方式吗?欢迎指教:)

static struct fb_fix_screeninfo anakinfb_fix = {

       .id          = "AnakinFB",

       .smem_start   = VGA_START,

       .smem_len     = VGA_SIZE,

       .type             = FB_TYPE_PACKED_PIXELS,

       .visual    = FB_VISUAL_TRUECOLOR,

       .line_length    = 400*2,

       .accel            = FB_ACCEL_NONE,

};

 下面是一个操作符优先级问题

anakinfb_setcolreg()

{

// green & 0xfc00 >> 5green & 0xfc00 >> 5)相同,注意操作符的优先级

((u16 *)(info->pseudo_palette))[regno] = (red & 0xf800) | (green & 0xfc00 >> 5) | (blue & 0xf800 >> 11);

}


摘要:

通过一个一个framebuffer例子,复习了内存分配的应用。其中的framebuffer例子为网上流行的(确实有bug的),在编译运行的过程中又重新温习了好多差不多已经被遗忘的知识点,写出来和大家分享!
---------------------------------------------------------------------------------------------------------------------
声明:
      
此文为原创,欢迎转载,转载请保留如下信息
      
作者:聂飞(afreez
      
联系方式:afreez@sina.com (欢迎与作者交流)
      
初次发布时间:2006-06-08
      不经本人同意,不得用语商业或赢利性质目的,否则,作者有权追究相关责任!
-----------------------------------------------------------------------------

例子实现了直接写屏的功能,即把屏幕清空(变黑),程序的流程大致为:打开一个FrameBuffer设备;通过mmap调用把显卡的物理内存空间映射到用户空间;通过映射关系直接写内存。

 

头文件

fbtools.h


#ifndef _FBTOOLS_H_

#define _FBTOOLS_H_

 

#include

 

//a framebuffer device structure;

typedef struct fbdev{

               int fb;

               unsigned long fb_mem_offset;

               unsigned long fb_mem;

               struct fb_fix_screeninfo fb_fix;

               struct fb_var_screeninfo fb_var;

               char dev[20];

} FBDEV, *PFBDEV;

 

//open & init a frame buffer

//to use this function,

//you must set FBDEV.dev="/dev/fb0"

//or "/dev/fbX"

//it's your frame buffer.

int fb_open(PFBDEV pFbdev);

 

//close a frame buffer

int fb_close(PFBDEV pFbdev);

 

//get display depth

int get_display_depth(PFBDEV pFbdev);

 

 

//full screen clear

void fb_memset(void *addr, int c, size_t len);

 

#endif


 

测试文件,其中深颜色的注释部分为在我机器上测得的结果

fbtools.c

代码:


 

#include

#include

#include

#include

#include

#include

#include

#include

 

#include "fbtools.h"

 

#define TRUE          1

#define FALSE         0

#define MAX(x,y)        ((x)>(y)?(x):(y))

#define MIN(x,y)        ((x)<(y)?(x):(y))

 

//open & init a frame buffer

int fb_open(PFBDEV pFbdev)

{

               pFbdev->fb = open(pFbdev->dev, O_RDWR);// pFbdev->fb==3

               if(pFbdev->fb < 0)

               {

                               printf("Error opening %s: %m. Check kernel config\n", pFbdev->dev);

                               return FALSE;

               }

               if (-1 == ioctl(pFbdev->fb,FBIOGET_VSCREENINFO,&(pFbdev->fb_var)))

               {

                               printf("ioctl FBIOGET_VSCREENINFO\n");

                               return FALSE;

               }

               if (-1 == ioctl(pFbdev->fb,FBIOGET_FSCREENINFO,&(pFbdev->fb_fix)))

               {

                               printf("ioctl FBIOGET_FSCREENINFO\n");

                               return FALSE;

               }

              

               //map physics address to virtual address

               // pFbdev->fb_fix.smem_start=f0000000

               pFbdev->fb_mem_offset = (unsigned long)(pFbdev->fb_fix.smem_start) & (~PAGE_MASK);

// pFbdev->fb_fix.smem_len=100 0000 pFbdev->fb_mem_offset=0

// pFbdev->fb_mem =0

               pFbdev->fb_mem = (unsigned long int)mmap(NULL, pFbdev->fb_fix.smem_len +

                                          pFbdev->fb_mem_offset,

                               PROT_READ | PROT_WRITE, MAP_SHARED, pFbdev->fb, 0);

               if (-1L == (long) pFbdev->fb_mem)

               {

                               printf("mmap error! mem:%d offset:%d\n", pFbdev->fb_mem,

                                                      pFbdev->fb_mem_offset);

                               return FALSE;

               }

              

               return TRUE;

}

 

//close frame buffer

int fb_close(PFBDEV pFbdev)

{

               close(pFbdev->fb);

               pFbdev->fb=-1;

}

 

//get display depth

int get_display_depth(PFBDEV pFbdev);

{

               if(pFbdev->fb<=0)

               {

                               printf("fb device not open, open it first\n");

                               return FALSE;

               }

               return pFbdev->fb_var.bits_per_pixel;

}

 

//full screen clear

void fb_memset (void *addr, int c, size_t len)

{

    memset(addr, c, len);

}

 

//use by test

#define DEBUG

#ifdef DEBUG

main()

{

               FBDEV fbdev;

               memset(&fbdev, 0, sizeof(FBDEV));

               strcpy(fbdev.dev, "/dev/fb0");

               if(fb_open(&fbdev)==FALSE)

               {

                               printf("open frame buffer error\n");

                               return;

               }

               //注意,下面一行有bug

               fb_memset(fbdev.fb_mem + fbdev.fb_mem_offset, 0, fbdev.fb_fix.smem_len);

              

               fb_close(&fbdev);

}

#endif


编译

如果对上述代码直接进行编译的话,是不能成功的,即会出现类似下面的编译错误

#gcc –o fbtools fbtools.c

fbtools.c: In function `main`

fbtools.c:89:warning:passing arg 1 of `fb_memset` makes pointer from integer without a cast

 

对有问题的fbtools.c中的第89行代码(即加粗的有注释的那一行)进行如下操作

修改为:

fb_memset((void *)(fbdev.fb_mem+fbdev.fb_mem_offset), 0, fbdev.fb_fix.smem_len);

或者

unsigned long temp;

temp= fbdev.fb_mem+fbdev.fb_mem_offset;

fb_memset((void *)temp, 0, fbdev.fb_fix.smem_len);

 

可以成功编译成功

 

而修改为:

fb_memset((&)(fbdev.fb_mem+fbdev.fb_mem_offset), 0, fbdev.fb_fix.smem_len);

或者

unsigned long temp;

temp= fbdev.fb_mem+fbdev.fb_mem_offset;

fb_memset((&)temp, 0, fbdev.fb_fix.smem_len);

 

会输出:段错误

 

分析

函数原形为:void fb_memset (void *addr, int c, size_t len)

fbtools.c:89调用时传递的参数为:

fb_memset(fbdev.fb_mem+fbdev.fb_mem_offset, 0, fbdev.fb_fix.smem_len);

fbdev.fb_memfbdev.fb_mem_offset都是unsigned long类型的变量,它们的计算结果保存在一个临时的栈空间,传递调用时,其临时的地址是不能够传递到被调用的函数的,所以编译是同不过的。具体的可以参考内存分配的相关知识,记得《effective c++》一书里讲的很详细,可以参考。

至于修改后的:

fb_memset((&)temp, 0, fbdev.fb_fix.smem_len);

编译出现段错误,也是很好理解的,因为(&)temp不等于(void *)temp,也不等于

(void *)(fbdev.fb_mem+fbdev.fb_mem_offset),具体原因读者可以对照《effective c++》思考。


本文主要介绍了directfbrc文件的使用及参数的详细说明,在directfb应用程序启动做初始化阶段,都会去试图读取该文件。

摘要:
本文主要介绍了directfbrc文件的使用及参数的详细说明,在directfb应用程序启动做初始化阶段,都会去试图读取该文件。
---------------------------------------------------------------------------------------------------------------------
声明:
      
此文为原创,欢迎转载,转载请保留如下信息
      
作者:聂飞(afreez
      
联系方式:afreez@sina.com (欢迎与作者交流)
      
初次发布时间:2006-06-06
     
不经本人同意,不得用语商业或赢利性质目的,否则,作者有权追究相关责任!
-----------------------------------------------------------------------------

directfbrcDirectFB配置文件。它被所有的DirectFB应用程序在启动时读取,有两个这样的文件,一个是存放在/etc/direcfbrc,是个全局的,另一个是存放在$HOME/.directfbrc,它是个局部的,可以覆盖系统的设置。

需要注意的是,这两个文件都不是默认存在的,是需要你自己建立的,不要象我一样,刚开始的时候到处找也没有找到,呵呵。

directfbrc使用的参数也可以在命令行里传递给DirectFB应用程序,只需要加上前缀:--dfb:

 

相关语法:

directfbrc文件每一行包含一个变量。注释行以井号“#”开始,一直到行尾。空行被忽略。

许多参数只是一种开关,控制着一些特性的开/关。这些开关选项有一个no-变量,可以关闭相应的特性。下面介绍一些实用的参数和一些默认的参数。

 

参数:

以下参数可以在directfbrc文件中设定

system=

       设定使用的图形系统。默认使用Linux frame buffer (fbdev),但你也可以在SDLsdl)上运行DirectFB应用程序。其它的系统在将来可能会被扩展近来。

fbdev=

打开指定的frame buffer 设备,而不是默认的/dev/fb0

mode=x

设定默认的屏幕显示。如果不设定,DirectFB 将使用/etc/fb.modes 的第一个设定值。一些frame buffer 设备( vesafb) 不支持模式切换,而只能使用启动时设定的值。

depth=

使用二进制位数设置每像素默认的像素深度。如果没有指定,Dir

阅读(1088) | 评论(0) | 转发(0) |
0

上一篇:DirectFB初探1

下一篇:DirectFB初探3

给主人留下些什么吧!~~