📄 关于framebuffer的一些文章_ - 我的文章 - t_t.htm
字号:
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">在使用</SPAN><SPAN
lang=EN-US>Framebuffer</SPAN><SPAN
style="FONT-FAMILY: 宋体">时,</SPAN><SPAN lang=EN-US>Linux</SPAN><SPAN
style="FONT-FAMILY: 宋体">是将显卡置于图形模式下的.</SPAN></P>
<P class=MsoNormal><SPAN
style="FONT-FAMILY: 宋体">在应用程序中,一般通过将</SPAN><SPAN lang=EN-US>
FrameBuffer </SPAN><SPAN
style="FONT-FAMILY: 宋体">设备映射到进程地址空间的方式使用,比如下面的程序就打开</SPAN><SPAN
lang=EN-US> /dev/fb0 </SPAN><SPAN
style="FONT-FAMILY: 宋体">设备,并通过</SPAN><SPAN lang=EN-US> mmap
</SPAN><SPAN style="FONT-FAMILY: 宋体">系统调用进行地址映射,随后用</SPAN><SPAN
lang=EN-US> memset </SPAN><SPAN
style="FONT-FAMILY: 宋体">将屏幕清空(这里假设显示模式是</SPAN><SPAN lang=EN-US>
1024x768-8 </SPAN><SPAN
style="FONT-FAMILY: 宋体">位色模式,线性内存模式):</SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US>int fb;</SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US>unsigned char*
fb_mem;</SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US>fb = open ("/dev/fb0",
O_RDWR);</SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US>fb_mem = mmap (NULL, 1024*768,
PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);</SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US>memset (fb_mem, 0,
1024*768);</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 21pt"><SPAN
lang=EN-US>FrameBuffer </SPAN><SPAN
style="FONT-FAMILY: 宋体">设备还提供了若干</SPAN><SPAN lang=EN-US> ioctl
</SPAN><SPAN
style="FONT-FAMILY: 宋体">命令,通过这些命令,可以获得显示设备的一些固定信息(比如显示内存大小)、与显示模式相关的可变信息(比如分辨率、象素结构、每扫描线的字节宽度),以及伪彩色模式下的调色板信息等等。</SPAN></P>
<P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">通过</SPAN><SPAN
lang=EN-US> FrameBuffer </SPAN><SPAN
style="FONT-FAMILY: 宋体">设备,还可以获得当前内核所支持的加速显示卡的类型(通过固定信息得到),这种类型通常是和特定显示芯片相关的。比如目前最新的内核(</SPAN><SPAN
lang=EN-US>2.4.9</SPAN><SPAN
style="FONT-FAMILY: 宋体">)中,就包含有对</SPAN><SPAN lang=EN-US>
S3</SPAN><SPAN style="FONT-FAMILY: 宋体">、</SPAN><SPAN
lang=EN-US>Matrox</SPAN><SPAN style="FONT-FAMILY: 宋体">、</SPAN><SPAN
lang=EN-US>nVidia</SPAN><SPAN style="FONT-FAMILY: 宋体">、</SPAN><SPAN
lang=EN-US>3Dfx </SPAN><SPAN
style="FONT-FAMILY: 宋体">等等流行显示芯片的加速支持。在获得了加速芯片类型之后,应用程序就可以将</SPAN><SPAN
lang=EN-US> PCI </SPAN><SPAN
style="FONT-FAMILY: 宋体">设备的内存</SPAN><SPAN lang=EN-US>I/O</SPAN><SPAN
style="FONT-FAMILY: 宋体">(</SPAN><SPAN lang=EN-US>memio</SPAN><SPAN
style="FONT-FAMILY: 宋体">)映射到进程的地址空间。这些</SPAN><SPAN lang=EN-US> memio
</SPAN><SPAN
style="FONT-FAMILY: 宋体">一般是用来控制显示卡的寄存器,通过对这些寄存器的操作,应用程序就可以控制特定显卡的加速功能。</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 21pt"><SPAN lang=EN-US>PCI
</SPAN><SPAN
style="FONT-FAMILY: 宋体">设备可以将自己的控制寄存器映射到物理内存空间,而后,对这些控制寄存器的访问,给变成了对物理内存的访问。因此,这些寄存器又被称为</SPAN><SPAN
lang=EN-US>"memio"</SPAN><SPAN
style="FONT-FAMILY: 宋体">。一旦被映射到物理内存,</SPAN><SPAN lang=EN-US>Linux
</SPAN><SPAN style="FONT-FAMILY: 宋体">的普通进程就可以通过</SPAN><SPAN
lang=EN-US> mmap </SPAN><SPAN
style="FONT-FAMILY: 宋体">将这些内存</SPAN><SPAN lang=EN-US> I/O
</SPAN><SPAN
style="FONT-FAMILY: 宋体">映射到进程地址空间,这样就可以直接访问这些寄存器了。</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 21pt"><SPAN
style="FONT-FAMILY: 宋体">当然,因为不同的显示芯片具有不同的加速能力,对</SPAN><SPAN
lang=EN-US>memio </SPAN><SPAN
style="FONT-FAMILY: 宋体">的使用和定义也各自不同,这时,就需要针对加速芯片的不同类型来编写实现不同的加速功能。比如大多数芯片都提供了对矩形填充的硬件加速支持,但不同的芯片实现方式不同,这时,就需要针对不同的芯片类型编写不同的用来完成填充矩形的函数。</SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US>FrameBuffer </SPAN><SPAN
style="FONT-FAMILY: 宋体">只是一个提供显示内存和显示芯片寄存器从物理内存映射到进程地址空间中的设备。所以,对于应用程序而言,如果希望在</SPAN><SPAN
lang=EN-US> FrameBuffer </SPAN><SPAN
style="FONT-FAMILY: 宋体">之上进行图形编程,还需要自己动手完成其他许多工作。</SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US><!--[if
!supportEmptyParas]--> <!--[endif]--><O:P></O:P></SPAN></P>
<P class=MsoNormal
style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt"><!--[if
!supportLists]--><SPAN lang=EN-US
style="FONT-FAMILY: 宋体">二、</SPAN><!--[endif]--><SPAN
lang=EN-US>FrameBuffer</SPAN><SPAN
style="FONT-FAMILY: 宋体">在</SPAN><SPAN lang=EN-US>LINUX</SPAN><SPAN
style="FONT-FAMILY: 宋体">中实现和机制</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 21pt"><SPAN
lang=EN-US>Framebuffer</SPAN><SPAN
style="FONT-FAMILY: 宋体">对应的源文件在</SPAN><SPAN
lang=EN-US>linux/drivers/video/</SPAN><SPAN
style="FONT-FAMILY: 宋体">目录下。总的抽象设备文件为</SPAN><SPAN
lang=EN-US>fbcon.c</SPAN><SPAN
style="FONT-FAMILY: 宋体">,在这个目录下还有与各种显卡驱动相关的源文件。</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 21.75pt"><SPAN
lang=EN-US>(</SPAN><SPAN style="FONT-FAMILY: 宋体">一</SPAN><SPAN
lang=EN-US>)</SPAN><SPAN style="FONT-FAMILY: 宋体">、分析</SPAN><SPAN
lang=EN-US>Framebuffer</SPAN><SPAN
style="FONT-FAMILY: 宋体">设备驱动</SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US><SPAN>
</SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体">需要特别提出的是在</SPAN><SPAN
lang=EN-US>INTEL</SPAN><SPAN
style="FONT-FAMILY: 宋体">平台上,老式的</SPAN><SPAN lang=EN-US>VESA 1.2
</SPAN><SPAN style="FONT-FAMILY: 宋体">卡,如</SPAN><SPAN
lang=EN-US>CGA/EGA</SPAN><SPAN
style="FONT-FAMILY: 宋体">卡,是不能支持</SPAN><SPAN
lang=EN-US>Framebuffer</SPAN><SPAN
style="FONT-FAMILY: 宋体">的,因为</SPAN><SPAN
lang=EN-US>Framebuffer</SPAN><SPAN
style="FONT-FAMILY: 宋体">要求显卡支持线性帧缓冲,即</SPAN><SPAN
lang=EN-US>CPU</SPAN><SPAN
style="FONT-FAMILY: 宋体">可以访问显缓冲中的每一位,但是</SPAN><SPAN lang=EN-US>VESA
1.2 </SPAN><SPAN style="FONT-FAMILY: 宋体">卡只能允许</SPAN><SPAN
lang=EN-US>CPU</SPAN><SPAN style="FONT-FAMILY: 宋体">一次访问</SPAN><SPAN
lang=EN-US>64K</SPAN><SPAN style="FONT-FAMILY: 宋体">的地址空间。</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 21.75pt"><SPAN
lang=EN-US>FrameBuffer</SPAN><SPAN
style="FONT-FAMILY: 宋体">设备驱动基于如下两个文件:</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 0.75pt"><SPAN lang=EN-US>1)
linux/include/linux/fb.h<BR>2)
linux/drivers/video/fbmem.c</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 0.75pt"><SPAN
style="FONT-FAMILY: 宋体">下面分析这两个文件。</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 27pt"><SPAN
lang=EN-US>1</SPAN><SPAN style="FONT-FAMILY: 宋体">、</SPAN><SPAN
lang=EN-US>fb.h</SPAN></P>
<P class=MsoNormal style="TEXT-INDENT: 27pt"><SPAN
lang=EN-US><SPAN> </SPAN></SPAN><SPAN
style="FONT-FAMILY: 宋体">几乎主要的结构都是在这个中文件定义的。这些结构包括:</SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US>1</SPAN><SPAN
style="FONT-FAMILY: 宋体">)</SPAN><SPAN
lang=EN-US>fb_var_screeninfo</SPAN></P>
<P class=MsoNormal><SPAN lang=EN-US><SPAN> </SPAN><SPAN>
</SPAN></SPAN><SPAN
style="FONT-FAMILY: 宋体">这个结构描述了显示卡的特性:</SPAN></P>
<P style="LINE-HEIGHT: 14pt"><SPAN lang=EN-US
style="FONT-SIZE: 10.5pt">struct fb_var_screeninfo
<O:P></O:P></SPAN></P>
<P style="LINE-HEIGHT: 14pt"><SPAN lang=EN-US
style="FONT-SIZE: 10.5pt">{<BR>__u32 xres; /* visible resolution
*/<BR>__u32 yres;<BR>__u32 xres_virtual; /* virtual resolution
*/<BR>__u32 yres_virtual;<BR>__u32 xoffset; /* offset from virtual
to visible resolution */<BR>__u32 yoffset; <O:P></O:P></SPAN></P>
<P style="LINE-HEIGHT: 14pt"><SPAN lang=EN-US
style="FONT-SIZE: 10.5pt">__u32 bits_per_pixel; /* guess what
*/<BR>__u32 grayscale; /* != 0 Gray levels instead of colors
*/<O:P></O:P></SPAN></P>
<P style="LINE-HEIGHT: 14pt"><SPAN lang=EN-US
style="FONT-SIZE: 10.5pt">struct fb_bitfield red; /* bitfield in fb
mem if true color, */<BR>struct fb_bitfield green; /* else only
length is significant */<BR>struct fb_bitfield blue;<BR>struct
fb_bitfield transp; /* transparency */<O:P></O:P></SPAN></P>
<P style="LINE-HEIGHT: 14pt"><SPAN lang=EN-US
style="FONT-SIZE: 10.5pt">__u32 nonstd; /* != 0 Non standard pixel
format */<O:P></O:P></SPAN></P>
<P style="LINE-HEIGHT: 14pt"><SPAN lang=EN-US
style="FONT-SIZE: 10.5pt">__u32 activate; /* see FB_ACTIVATE_*
*/<O:P></O:P></SPAN></P>
<P style="LINE-HEIGHT: 14pt"><SPAN lang=EN-US
style="FONT-SIZE: 10.5pt">__u32 height; /* height of picture in mm
*/<BR>__u32 width; /* width of picture in mm
*/<O:P></O:P></SPAN></P>
<P style="LINE-HEIGHT: 14pt"><SPAN lang=EN-US
style="FONT-SIZE: 10.5pt">__u32 accel_flags; /* acceleration flags
(hints) */<O:P></O:P></SPAN></P>
<P style="LINE-HEIGHT: 14pt"><SPAN lang=EN-US
style="FONT-SIZE: 10.5pt">/* Timing: All values in pixclocks, except
pixclock (of course) */<BR>__u32 pixclock; /* pixel clock in ps
(pico seconds) */<BR>__u32 left_margin; /* time from sync to picture
*/<BR>__u32 right_margin; /* time from picture to sync */<BR>__u32
upper_margin; /* time from sync to picture */<BR>__u32
lower_margin;<BR>__u32 hsync_len; /* length of horizontal sync
*/<BR>__u32 vsync_len; /* length of vertical sync */<BR>__u32 sync;
/* see FB_SYNC_* */<BR>__u32 vmode; /* see FB_VMODE_* */<BR>__u32
reserved[6]; /* Reserved for future compatibility
*/<BR>};<O:P></O:P></SPAN></P>
<P style="LINE-HEIGHT: 14pt"><SPAN lang=EN-US
style="FONT-SIZE: 10.5pt">2)
fb_fix_screeninfon<BR>这个结构在显卡被设定模式后创建,它描述显示卡的属性,并且系统运行时不能被修改;比如FrameBuffer内存的起始地址。它依赖于被设定的模式,当一个模式被设定后,内存信息由显示卡硬件给出,内存的位置等信息就不可以修改。<O:P></O:P></SPAN></P>
<P style="LINE-HEIGHT: 14pt"><SPAN lang=EN-US
style="FONT-SIZE: 10.5pt">struct fb_fix_screeninfo {<BR>char id[16];
/* identification string eg "TT Builtin" */<BR>unsigned long
smem_start; /* Start of frame buffer mem */<BR>/* (physical address)
*/<BR>__u32 smem_len; /* Length of frame buffer mem */<BR>__u32
type; /* see FB_TYPE_* */<BR>__u32 type_aux; /* Interleave for
interleaved Planes */<BR>__u32 visual; /* see FB_VISUAL_*
*/<BR>__u16 xpanstep; /* zero if no hardware panning */<BR>__u16
ypanstep; /* zero if no hardware panning */<BR>__u16 ywrapstep; /*
zero if no hardware ywrap */<BR>__u32 line_length; /* length of a
line in bytes */<BR>unsigned long mmio_start; /* Start of Memory
Mapped I/O */<BR>/* (physical address) */<BR>__u32 mmio_len; /*
Length of Memory Mapped I/O */<BR>__u32 accel; /* Type of
acceleration available */<BR>__u16 reserved[3]; /* Reserved for
future compatibility */<BR>};<O:P></O:P></SPAN></P>
<P style="LINE-HEIGHT: 14pt"><SPAN lang=EN-US
style="FONT-SIZE: 10.5pt">3)
fb_cmap<BR>描述设备无关的颜色映射信息。可以通过FBIOGETCMAP 和 FBIOPUTCMAP
对应的ioctl操作设定或获取颜色映射信息.<O:P></O:P></SPAN></P>
<P style="LINE-HEIGHT: 14pt"><SPAN lang=EN-US
style="FONT-SIZE: 10.5pt">struct fb_cmap {<BR>__u32 start; /* First
entry */<BR>__u32 len; /* Number of entries */<BR>__u16 *red; /* Red
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -