framebuffer 简介

news/2024/7/8 5:34:38 标签: linux, buffer, 工作, 图形, 编程, null

FrameBuffer 是出现在 2.2.xx 内核当中的一种驱动程序接口。Linux 工作在保护模式下,所以用户态进程是无法象 DOS 那样使用显卡 BIOS 里提供的中断调用来实现直接写屏,Linux 抽象出 FrameBuffer 这个设备来供用户态进程实现直接写屏。Framebuffer 机制模仿显卡的功能,将显卡硬件结构抽象掉,可以通过 Framebuffer 的读写直接对显存进行操作。用户可以将 framebuffer 看成是显示内存的一个映像,将其映射到进程地址空间之后,就可以直接进行读写操作,而写操作可以立即反应在屏幕上。这种操作是抽象的,统一的。用户不必关 心物理显存的位置、换页机制等等具体细节。这些都是由 framebuffer 设备驱动来完成的。

framebuffer 本身不具备任何运算数据的能力,就只好比是一个暂时存放水的水池.CPU 将运算后的结果放到这个水池,水池再将结果流到显示器.中间不会对数据做处理. 应用程序也可以直接读写这个水池的内容.在这种机制下,尽管 framebuffer 需要真正的显卡驱动的支持,但所有显示任务都有 CPU 完成,因此 CPU 负担很重.

帧缓冲驱动应用广泛,在 linux 的桌面系统中,X window 服务器就是利用帧缓 冲进行窗口的绘制。尤其是通过帧缓冲可显示汉字点阵,成为Linux 汉化的唯一可 行方案。

在开发者看来,FrameBuffer 本质上是一块显示缓存,往显示缓存中写入特定格 式的数据就意味着向屏幕输出内容。所以说 FrameBuffer 就是一块白板。例如 对于初始化为 16 位色的 FrameBuffer 来说, FrameBuffer 中的两个字节代表屏幕上一个点,从上到下,从左至右,屏幕位置与内存地址是 顺序的线性关系。

帧缓存可以在系统存储器(内存)的任意位置,视频控制器通过访问帧缓存来刷新 屏幕。 帧缓存也叫刷新缓存 Frame buffer 或 refresh buffer, 这里的帧(frame)是指整个屏幕范围。

帧缓存有个地址,是在内存里。我们通过不停的向 frame buffer 中写入数据, 显示控制器就自动的从 frame buffer 中取数据并显示出来。全部的图形都共享内 存中同一个帧缓存。

CPU 指定显示控制器工作,则显示控制器根据CPU的控制到指定的地方去取数据 和指令, 目前的数据一般是从显存里取, 如果显存里存不下,则从内存里取, 内存也放不下,则从硬盘里取,当然也不是内存放不下,而是为了节省内存的话, 可以放在硬盘里,然后通过 指令控制显示控制器去取。帧缓存 Frame Buffer 里面存储的东西是一帧一帧的, 显卡会不停的刷新 Frame Buffer, 这每一帧如 果不捕获的话, 则会被丢弃,也就是说是实时的。这每一帧不管是保存在内存 还是显存里, 都是一个显性的信息, 这每一帧假设是 800x600 的分辨率, 则保 存的是 800x600 个像素点,和颜色值。

如何启用 framebuffer

首先确认内核是否支持 framebuffer ,查看 /proc/fb 文件是否存在,存在则 说明支持,否则,说明不支持。其次查看 framebuffer 设备是否已激活,若 /dev/fbx 文件存在,则说明已经 激活;否则说明没有激活。

在系统启动时可通过向 kernel 传送 vga=mode-number 的参数来激活 FrameBuffer 设备,如 vga=0x314,将会启动 800*600*16bpp 模式 要 linux 缺省激活 framebuffer 设备,需要将/etc/grub.conf改成如下形式:

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You do not have a /boot partition. This means that
# all kernel and initrd paths are relative to /, eg.
# root (hd0,0)
# kernel /boot/vmlinuz-version ro root=/dev/sda1
# initrd /boot/initrd-version.img
#boot=/dev/sda
default=0
timeout=10
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
title Red Hat Linux (2.4.18-14)
root (hd0,0)
kernel /boot/vmlinuz-2.4.18-14 ro root=LABEL=/ hdc=ide-scsi vga=0x314
initrd /boot/initrd-2.4.18-14.img
  
0x314 表示 800*600*16bpp,其它取值见下表: 
color640x400640x480800x6001024x7681280x10241600x1200
4bits??0x302???
8bits0x3000x3010x3030x3050x3070x31C
15bits?0x3100x3130x3160x3190x31D
16bits?0x3110x3140x3170x31A0x31E
24bits?0x3120x3150x3180x31B0x31F
32bits??????

framebuffer 设备启用后,在重启系统时屏幕左上方会显示一个小企鹅。

如何编程操作 framebuffer

帧缓冲设备对应的设备文件为/dev/fb*,如果系统有多个显示卡,Linux 下还可 支持多个帧缓冲设备,最多可达 32 个,分别为 /dev/fb0 到 /dev/fb31 ,而 /dev/fb 则为当前缺省的帧缓冲设备,通常指向 /dev/fb0 。当然在嵌入式系统 中支持一个显示设备就够了。帧缓冲设备为标准字符设备,主设备号为 29,次 设备号则从 0 到 31 ,分别对应 /dev/fb0 至 /dev/fb31 。通过 /dev/fb ,应用程序的操作主要有这几种:

  1. 读/写(read/write)/dev/fb 文件:相当于读/写屏幕缓冲区。通过 seek 接口定位读写位置,通过 read/write 接口读写具体数据;
  2. 映射(map)操作:由于 Linux 工作在保护模式,每个应用程序都有自己的 虚拟地址空间,在应用程序中是不能直接访问物理缓冲区地址的。为此, Linux 在文件操作 file_operations 结构中提供了 mmap 函数,可将文件的内容映射到用户空间。对于帧缓冲设备,则可通过映射操作,可将屏幕缓冲区的物理地址映射到用户空间的一段虚拟地址中,之后用户就可以通过 读写这段虚拟地址访问屏幕缓冲区,在屏幕上绘图了。实际上,使用帧缓冲设备的应用程序都是通过映射操作来显示图形的。由于映射操作都是由内核来完成,下面 我们将看到,帧缓冲驱动留给开发人员的工作并不多。
  3. I/O控制:对于帧缓冲设备,对设备文件的ioctl操作可读取/设置显示设备及屏幕的参数,如分辨率,显示颜色数,屏幕大小等等。ioctl的 操作是由底层的驱动程序来完成的。

在应用程序中,一般通过将 framebuffer 设备映射到进程地址空间的方式使用, 比如下面的程序就打开 /dev/fb0 设备,并通过 mmap 系统调用进行地址映射, 随后用 memset 将屏幕清空(这里假设显示模式是 1024x768-8 位色模式,线性 内存模式):

int fb;
unsigned char* fb_mem;
fb = open ("/dev/fb0", O_RDWR);
fb_mem = mmap (NULL, 1024*768, PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);
memset (fb_mem, 0, 1024*768);
 
  framebuffer 设备还提供了若干 ioctl 命令,通过这些命令,可以获得显示设备的一些固定信息(比如
显示内存大小)、与显示模式相关的可变信息(比如分辨率、象素结构、每扫描线的字节宽度),以及
伪彩色模式下的调色板信息等等。 
 
通过 framebuffer 设备,还可以获得当前内核所支持的加速显示卡的类型(通过固定信息得到),
这种类型通常是和特定显示芯片相关的。比如目前最新的内核(2.4.9)中,就包含有对 S3、Matrox、
nVidia、3Dfx 等等流行显示芯片的加速支持。在获得了加速芯片类型之后,应用程序就可以将 PCI 设备
的内存I/O(memio)映射到进程的地址空间。这些 memio 一般是用来控制显示卡的寄存器,通过对
这些寄存器的操作,应用程序就可以控制特定显卡的加速功能。
  
PCI 设备可以将自己的控制寄存器映射到物理内存空间,而后,对这些控制寄存器的访问,给变成了对
物理内存的访问。因此,这些寄存器又被称为"memio"。一旦被映射到物理内存,Linux 的普通进程就可
以通过 mmap 将这些内存 I/O映射到进程地址空间,这样就可以直接访问这些寄存器了。
  
当然,因为不同的显示芯片具有不同的加速能力,对memio 的使用和定义也各自不同,这时,就需要针
对加速芯片的不同类型来编写实现不同的加速功能。比如大多数芯片都提供了对矩形填充的硬件加速支持,
但不同的芯片实现方式不同,这时,就需要针对不同的芯片类型编写不同的用来完成填充矩形的函数。
  
framebuffer 只是一个提供显示内存和显示芯片寄存器从物理内存映射到进程地址空间中的设备。所以,
对于应用程序而言,如果希望在 framebuffer 之上进行图形编程,还需要自己动手完成其他许多工作 

工具

cat

/dev/fb 是一个文件,因此我们可以用对其读写。

cat /dev/fb0 > screensnap.txt /* read current sreen to a file*/
cat screensnap.txt > /dev/fb0 /* 将 screensnap.txt 的内容贴到屏幕上 */
 
 
  dd
 
   可以用如下命令清空屏幕: 
dd if=/dev/zero of=/dev/fb
如果显示模式是 1024x768-8 位色,用如下命令清空屏幕:
  dd if=/dev/zero of=/dev/fb0 bs=1024 count=768
  用如下命令可以将fb中的内容保存下来和重新写回屏幕: 
 dd if=/dev/fb of=fbfile
dd if=fbfile of=/dev/fb 
 
 
fbset
 
   fbset是一个可以查看和设置framebuffer的工具。具体使用方法可参看手册。

转载  什么是FrameBuffer? 收藏

FrameBuffer 是出现在 2.2.xx 内核当中的一种驱动程序接口。这种接口将显示设 备抽象为帧缓冲区。用户可以将它看成是显示内存的一个映像,将其映射到进程地 址空间之后,就可以直接进行读写操作,而写操作可以立即反应在屏幕上。该驱动 程序的设备文件一般是 /dev/fb0、/dev/fb1 等等。比如,假设现在的显示模式是 1024x768-8 位色,则可以通过如下的命令清空屏幕:

$ dd if=/dev/zero of=/dev/fb0 bs=1024 count=768
在应用程序中,一般通过将 FrameBuffer 设备映射到进程地址空间的方式使用, 比如下面的程序就打开 /dev/fb0 设备,并通过 mmap 系统调用进行地址映射,随 后用 memset 将屏幕清空(这里假设显示模式是 1024x768-8 位色模式,线性内存 模式):
int fb; unsigned char* fb_mem;
fb = open ("/dev/fb0", O_RDWR); fb_mem = mmap (NULL, 1024*768, PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);
memset (fb_mem, 0, 1024*768);
FrameBuffer 设备还提供了若干 ioctl 命令,通过这些命令,可以获得显示设备 的一些固定信息(比如显示内存大小)、与显示模式相关的可变信息(比如分辨 率、象素结构、每扫描线的字节宽度),以及伪彩色模式下的调色板信息等等。
通过 FrameBuffer 设备,还可以获得当前内核所支持的加速显示卡的类型(通过 固定信息得到),这种类型通常是和特定显示芯片相关的。比如目前最新的内核 (2.4.9)中,就包含有对 S3、Matrox、nVidia、3Dfx 等等流行显示芯片的加速 支持。在获得了加速芯片类型之后,应用程序就可以将 PCI 设备的内存I/O (memio)映射到进程的地址空间。这些 memio 一般是用来控制显示卡的寄存器, 通过对这些寄存器的操作,应用程序就可以控制特定显卡的加速功能。
PCI 设备可以将自己的控制寄存器映射到物理内存空间,而后,对这些控制寄存器 的访问,给变成了对物理内存的访问。因此,这些寄存器又被称为"memio"。一旦 被映射到物理内存,Linux 的普通进程就可以通过 mmap 将这些内存 I/O 映射到 进程地址空间,这样就可以直接访问这些寄存器了。
当然,因为不同的显示芯片具有不同的加速能力,对memio 的使用和定义也各自不 同,这时,就需要针对加速芯片的不同类型来编写实现不同的加速功能。比如大多 数芯片都提供了对矩形填充的硬件加速支持,但不同的芯片实现方式不同,这时, 就需要针对不同的芯片类型编写不同的用来完成填充矩形的函数。
说到这里,读者可能已经意识到 FrameBuffer 只是一个提供显示内存和显示芯片 寄存器从物理内存映射到进程地址空间中的设备。所以,对于应用程序而言,如果 希望在 FrameBuffer 之上进行图形编程,还需要完成其他许多工作。举个例子来 讲,FrameBuffer 就像一张画布,使用什么样子的画笔,如何画画,还需要你自己 动手完成。

来源: http://blog.csdn.net/guyun_shine/article/details/6019617

http://www.niftyadmin.cn/n/1736424.html

相关文章

对FrameBuffer的简单解释和用法示例

大家都知道Unix/Linux系统是由命令驱动的。那么最基本的系统是命令行的(就是想DOS一样的界面)。X-Window-System是Unix/Linux上的图形系统,它是通过X-Server来控制硬件的。但有一些Linux的发行版在引导的时…

mmap与内存管理

mmap与内存管理- mmap系统调用的编程实例 收藏 1 mmap的使用 mmap地址映射是Linux系统提供的一种功能强大的系统调用&#xff0c;最典型的应用是用于显卡内存的映射。同样&#xff0c;对于普通的硬盘文件也可以进行mmap系统调用。 #include <sys/mman.h> void * m…

linux spi驱动分析

关于spi的学习&#xff0c;我觉得最好的方法还是看Linux的源代码&#xff0c;主要是driver/spi/spi.c(h)&#xff0c;spidev.c(h)。spi dev的示例可以看看at25.c&#xff0c;spi总线的示例可以看omap_uwire或者spi_s3c24xx.c和spi_s3c24xx_gpio.c。在看这些代码之前&#xff0c…

小议大小端模式对C语言的共用体结构的影响

小议大小端模式对C语言的共用体结构的影响 1、一些问题 问题1 view plaincopy to clipboardprint?#include "stdio.h" union { int i; char ch[2]; }key; main() { key.i65*25666; printf("%c\t%c\n",key.ch[0],key.ch[1]); …

Linux下SPI驱动分析

Linux下SPI总线驱动有通用接口&#xff0c;一般的SPI设备驱动使用这个驱动接口实现设备驱动。分析驱动最好是先了解核心代码&#xff0c;然后从具体设备分析入手&#xff0c;然后从下至上&#xff0c;了解整个框架&#xff0c;再从上到下分析&#xff0c;理解透彻。 以下分析内…

Linux驱动修炼之道-SPI驱动框架源码分析(上)

努力成为linux kernel hacker的人李万鹏原创作品&#xff0c;为梦而战。转载请标明出处 http://blog.csdn.net/woshixingaaa/archive/2011/06/29/6574215.aspx Linux驱动修炼之道-SPI驱动框架源码分析(中) Linux驱动修炼之道-SPI驱动框架源码分析(下) SPI协议是一种同步的串…

Linux驱动修炼之道-SPI驱动框架源码分析(中)

努力成为linux kernel hacker的人李万鹏原创作品&#xff0c;为梦而战。转载请标明出处 http://blog.csdn.net/woshixingaaa/archive/2011/06/29/6574220.aspx 这篇来分析spi子系统的建立过程。 嵌入式微处理器访问SPI设备有两种方式&#xff1a;使用GPIO模拟SPI接口的工作时序…

Linux驱动修炼之道-SPI驱动框架源码分析(下)

努力成为linux kernel hacker的人李万鹏原创作品&#xff0c;为梦而战。转载请标明出处 http://blog.csdn.net/woshixingaaa/article/details/6574224 这篇文档主要介绍spi数据传输过程。 当应用层要向设备传输数据的时候&#xff0c;会通过ioctl向设备驱动发送传输数据的…