Frame Buffer 设备
0、 简介 Frame Buffer设备为图形硬件提供抽象。它表示一些视频硬件的Frame Buffer,允许应用软件通过定义好的接口访问图形硬件,所以这些软件不必知道任何关于低层(硬件寄存器)的知识。 设备通过特殊的设备节点来访问,通常这些节点位于/dev目录,即/dev/fb*。 1、 从用户来看/dev/fb* 从用户的观点来看,Frame Buffer设备就如位于/dev目录下的其他设备。它是一个字符设备使用主设备号29;次设备号指定了frame buffer号。 按照习惯,使用下列的设备节点(号码指定设备的次设备号): 0 = /dev/fb0第1个frame buffer 1 = /dev/fb1第2个frame buffer ... 31 = /dev/fb31 第32个frame buffer 考虑向后兼容,你可能需要创建下面的符号连接: /dev/fb0current -> fb0 /dev/fb1current -> fb1 等等... frame buffer设备也是“通常”的内存设备,意味着,你可以读或者写他们的内容。例如,你可以截屏 cp /dev/fb0 myfile 某一时刻可以存在多个frame buffer,就是说,如果你在固定的硬件上附加一个图形卡。相应的frame buffer 设备(/dev/fb0和/dev/fb1等等)可以独立的工作。 使用frame buffer设备的应用程序(例如 X server)默认使用/dev/fb0(老一点的软件使用 /dev/fb0current)。你可以 通过设定环境变量$FRAMEBUFFER等于frame buffer设备的路径名来改变frame buffer设备,例如(针对 sh/bash 用户): export FRAMEBUFFER=/dev/fb1 或者(针对 csh 用户): setenv FRAMEBUFFER /dev/fb1 之后,X server将使用第二个frame buffer。 2、 从程序员来看 /dev/fb* 大家都已经知道,frame buffer设备是一个内存设备,就像/dev/mem, 所以他拥有相同的特征。你可以读他,写他,在他里面定位和mmap他(主要用途)。不同点在于在特殊文件中的通常的内存不是整体的内存(译注:whole memory),但是一些视频硬件的frame buffer是。 /dev/fb*也允许在他之上做一些ioctls操作,通过这种方法硬件的许 多信息可以获取和设置。颜色映射处理(the color map handling)也通过ioctls工作。查看<linux/fb.h>取得更多的信息关于ioctls怎么存在,和赖以工作的数据结构。 这里仅仅是简要的预览: - 你可以取得硬件的不可更改信息,例如名字,屏幕内存组织方式(位面,象素格式,……)和地址和屏幕内存的长度。 - 你可以获取和修改硬件的可变信息,例如可见,虚拟几何,深度,颜色映射格式,定时,等等。 如 果你试图修改这些信息,驱动可能规整一些值以适应硬件的能力(或者返回EINVAL 如果这个操作不可能) (译注:the driver maybe will round up some values to meet the hardware's capabilities) - 你可以取得和设置部分颜色映射。通信使用16位每一颜色(红,绿,蓝,透明)来支持所有存在的硬件。驱动处理所有应用于硬件的计算(截取他们到较少的位,可能会舍弃透明)。 所 有的这些硬件抽象使得应用程序的实现变得容易和更加易于移植。例如,X server完全工作在/dev/fb*,所以不必要知道,诸如具体的硬件上关联的颜色是怎么组织的。XF68_FBDEV是针对位图和没有视频硬件加速 的通用X server。仅有的需要应用程序处理的是屏幕的组织方式(位面或者象素块等等),因为它直接工作于frame buffer图像模式。 在未来,计划把图形卡相关的frame buffer驱动实现为内核模块,以便在允许时加载。这样的驱动只需要调用register_framebuffer()和提供一些函数。独立于内核的编写和分发这样的驱动,将会省掉许多问题…… 3、 Frame Buffer分辨率维护 Frame Buffer分别绿使用'fbset'来维护。它可以更改frame buffer设备的视频模式属性。它的主要用途是更改当前的视频模式,例如在引导时期在你的/etc/rc.*或者/etc/init.d/* 文件中。 fbset使用存储在配置文件中的视频模式数据库,所有你可以容易的添加你自己的模式并且使用简单的标识符引用他们。 4、 X server X server(XF68_FBDev)是使用frame buffer设备最著名的应用程序。从XFree86 release 3.2开始,X server成为 XFree86的组成部分,它有两个模式: - 如果供'fbdev'驱动使用的/etc/XF86Config文件的'Display'部分含有一行Modes "default"X server将使用上面提到的配置,即它将以/dev/fb0(或者 $FRAMEBUFFER,如果设定了)指定的分辨率启动。 你仍然需要指定颜色深度(使用关键字Depth)和虚拟分辨率(使用关键字Virtual)。这是随XFree86提供的配置 文件需要默认设定的项目。这是最简单的配置,但是它有一些限制。 - 因此,在/etc/XF86Conifg文件里指定分辩率也是可能的。这允许在保持同样的虚拟桌面尺寸动态的(译注:on-the-fly)切换分辨率。 使用的Frame Buffer设备仍然是/dev/fb0current(或者$FRAMEBUFFER),但是可用的分辨率现在由 /etc/XF86Config定义。缺点是,你必须以不同的格式指定时间(timings)(但是 'fbset -x'可以帮助你)。 为了调优显示模式,你可以使用fbset或者xvidtune。需要注意的是xvidtune对XF68_FBDev不一定工作:报告的时钟值通常是错误的。 5、 视频模式计时 显示器使用电子束(彩色模式使用3个电子束,单色模式使用1个电子束)绘制屏幕上的图像。屏幕的前面 被 颜色荧光(象素)覆盖.如果荧光被电子击中,它就会发出光子从而可见.电子束从左至右绘制水平行,从上到下绘制整个屏幕.通过改变电子束的亮度,便可以显 示各种颜色和亮度的像素.每条扫描线完成后电子束必须重新移回到下一行的左端:这称做水平回扫.等到完成整个屏幕(帧)的绘制,电子束会移回到左上方点: 这被称做垂直回扫.在水平和垂直回扫期间,电子束被关闭(空). 电子束绘制像素的速度由图形板的时钟(译注:dotclock).例如时钟是 28.37516MHZ(每秒百万周期),每像素需35242 ps(微秒):1/(28.37516E6 HZ) = 35.242E-9 s如果屏幕的分辨率是640x480, 将需要640*35.242E-9 s = 22.555E-6 s来绘制一条扫描线上640(xres)个像素.但是水平回扫也需要时间(例如 272 像素), 所以一条完整的水平扫描线需要: (640+272)*35.242E-9 s = 32.141E-6 s 我们称水平刷新率约是31 kHz: 1/(32.141E-6 s) = 31.113E3 Hz 整个屏幕有480(yres)条扫描线,但是我们必须还要考虑垂直回扫(例如 49 条扫描线). 所以完整的一屏需要: (480+49)*32.141E-6 s = 17.002E-3 s 垂直刷新率约是 59 Hz:1/(17.002E-3 s) = 48.815 Hz 这意味着屏幕上的数据每秒钟刷新约59此.为了得到稳定的图像没有视觉闪烁,VESA建议垂直扫描率不低于72 Hz. 不过是否闪烁跟人极大相关:一些人使用50 Hz感觉却很好, 然而当低于80 Hz时我就会觉察到. 下面的图片可以说明一切.水平回扫时间是左边缘,右边缘和 hsync 长度的总和. 而垂直回扫时间是上边缘,下边缘和 vsync长度的总和 . frame buffer设备期待所有的水平计时以时钟(以picoseconds, 1E-12 s)为单位, 垂直计时则以扫描线数目为单位. 6、 转换 XFree86 计时值信息到frame buffer设备计时 XFree86 模式行由以下域组成:"800x600" 50 800856 976 1040 600 637 643 666 < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL frame buffer设备使用以下的域: - pixclock: 以ps为单位的像素时钟(pico seconds) - left_margin: 从sync到画面的时间 - right_margin: 从画面到sync的时间 - upper_margin: 从sync到画面的时间 -lower_margin: 从画面到sync的时间 - hsync_len: 水平sync的长度 - vsync_len: 垂直sync的长度 1) 像素时钟: xfree: in MHz fb: in picoseconds (ps) pixclock = 1000000 / DCF 2) 水平计时: left_margin = HFL - SH2 right_margin = SH1 - HR hsync_len = SH2 - SH1 3) 垂直计时: upper_margin = VFL - SV2 lower_margin = SV1 - VR vsync_len = SV2 - SV1 针对VESA计时的很多例子可以在 XFree86 源代码树找到, 在"xc/programs/Xserver/hw/xfree86/doc/modeDB.txt"下. 7、 参考 更多的关于frame buffer 设备的信息和应用程序, 请参考 Linux-fbdev 网站: http://linux-fbdev.sourceforge.net/ 和下面的文档: - fbset的手册页: fbset(8), fb.modes(5) - XFree86的手册页: XF68_FBDev(1), XF86Config(4/5) - 内核源代码: o linux/drivers/video/ o linux/include/linux/fb.h o linux/include/video/ 8、 邮件列表 有一些与frame buffer设备相关的邮件列表存在于SourceForge: - [email protected], 用于通告, - [email protected], 用于对一般用户的支持, - [email protected], 用于项目开发人员. 登录到http://sourceforge.net/projects/linux-fbdev/ 这个网页 查看订阅信息. 9、 下载 所有必需的文件可以在下面的地址找到: ftp://ftp.uni-erlangen.de/pub/Linux/LOCAL/680x0/ 或者在它的镜像站点. 最新版本的fbset可以在下面找到: http://home.tvd.be/cr26864/Linux/fbdev/ 10、 致谢 这份说明文件由Geert Uytterhoeven编写,部分是基于最初的 由Roman Hodek和Martin Schaller编写的 'X-framebuffer.README'. 第六节由Frank Neumann提供. frame buffer设备抽象是由Martin Schaller设计的. 注:内核版本是2.6.12,本文件位于 linux/Documentation/fb |