如何编写Linux Framebuffer驱动(上)

原文: James Simmons, jsimmons@edgeglobal.com
翻译: 408-lodger

v1.00 1999.10.9

本文描述如何让Linux支持一块framebuffer显卡。文中列举了已支持的显卡硬件,描述了如何编写内核驱动,同时就一些频繁问及的问题作出解答。目的是让framebuffer驱动开发的新手和老手都能快速适应linux图形系统在开发方面的变化。

______________________________________________________________________ 

目录

1. 介绍 

1.1 常识 
1.2 历史回顾
1.3 新版本 
1.4 反馈 
1.5 发布条款 

2. Framebuffer显卡技术 

2.1 显示器 
2.2 显卡

3. 设置显示模式 

3.1 定频显示器 
3.2 变频显示器 
3.3 Receipe for multisync monitors 
3.4 Receipe for Monosync 
3.5 Clocks 
3.5.1 DCLK 
3.5.2 MCLK 
3.5.3 PLL 
3.6 CRTC寄存器 
3.7 色彩

4. Framebuffer 内部API 

4.1 数据结构
4.2 驱动层次

5. 常见问题解答 

5.1 fbdev支持硬件加速吗? 

6. 参考 

______________________________________________________________________ 

1. 介绍

本 文是关于怎样编写Linux Framebuffer驱动。意图想做为一本快速参考手册,涵盖在Linux下编写framebuffer显示驱动所需要知 道的方方面面。常被问到的Linux下显示模式设置的问题在这里作出了解答,参考引用中列举了与计算机图形学相关的各种主题的出处。如果你不是十分熟悉显 卡硬件的话,还请将本文多读几遍。

文章的范围限定为编写可设置显示模式的显卡的Linux framebuffer驱动。关于如何设置framebuffer显卡及XFB_Dev X服务器方面的更多常用信息,请参见“参考引用”一节列举的文章。

1.1. 常识

文 中的许多资料来源于由我开发的下一代内核中的新framebuffer内核API。这些最初都基于Fabrice Ballard的一个补丁。拜读之后给 我留下很深的印象。之后,我开始接手它的开发并对之改进。感谢Fabrice让它生生不息。这套API是原始由Martin Schaller开发的 API——目前由Geert Uytterhoeven(geert@linux-m68k.org)维护——的自然延续。谢谢你和那些开发了 Linux framebuffer系统,驱动和组件的人们。最要感谢的是GGI project的Andreas Beck,帮我撰写本文并教给我显示 模式设置方面的知识。同样还要感谢那些支持我工作的人。

感谢SGML工具包,本文有多种存储格式版本,都是(用它)从普通文件生成得来。

1.2. 历史回顾

版本 1.0
第一版; 仅通过fbdev邮件列表发送

1.3. 新版本

文本的新版本将周期性的公布在comp.os.linux.answers新闻组。同样也将上传到各个匿名ftp资料归档站点上,包括<::URL::ftp://metalabs.unc.edu/pub/Linux/docs/HOWTO/>.

本文及其它Linux HOWTO文集的超本文版本在许多万维网站点都可以找到,包括<::URL::http://metalab.unc.edu/LDP/>。许多Linux  CD-ROM发行版包含了HOWTO文集,通常存放在/usr/doc目录下,你还同样能从许多商家那里买到印刷本。有时从CD-ROM销售商、ftp 站点及印刷本上得来的HOWTO文集已经过时。如果你获得的HOWTO文件以是半年前的,那Internet可能已有更新的版本了。

更多本文及其它Linux HOWTO文集的译本可在<::URL::http: //sunsite.unc.edu/pub/Linux/docs/HOWTO/translations/>及<ftp: //sunsite.unc.edu/pub/Linux/docs/HOWTO/translations/>处找到。

如果你将本文翻译成其它语种,请让我获知,我将在这里提供引用。到目前为止还没有任何翻译版本。

1.4. 反馈

读者朋友,我依靠于你,将这篇HOWTO变成更加实用。如果你有任何建议,指正或者评注,都请发给我,jsimmons@edgeglobal.com,我将考虑在下一版本中合入。

同样我也乐意尽我所能地答复关于显卡和Linux fbcon方面的常见问题。但在这之前请完整阅读这篇HOWTO,然后再详细的告诉我哪里有问题。但请不要问我关于如何在其它非Linux系统下使用framebuffer显卡的问题。

如 果你在CD-ROM或印刷本上发布本文,那感谢你也赠送我一份。可以寄到我的邮箱里。为了支持Linux的自由文档事业,同样请考虑为Linux文档工程 捐献一份自己的力量。请联系Linux HOWTO的协调员Tim Bynum<linux-howto@sunsite.unc.edu> 获取更多信息。

1.5.发布条款

Copyright (c) 1999 by James Simmons. 发布文本需要遵循LDP条款<::URL::http://sunsite.unc.edu/LDP/COPYRIGHT.html>。

2. Framebuffer显卡技术

本节将对拥有可读写framebuffer技术的显卡作一个非常粗略的概述,目的是帮助你理解本文稍后将用到的概念。如果你打算为显卡写个驱动,那请联系制造商获得显卡手册。如果还想了解更多知识,请考虑阅读更多关于显卡硬件的书籍。

Linux 下framebuffer设备的表现就和/dev/mem这些很相似。实际上/dev/fb被当作内在设备对待,只不过这种情况下内存是一块显存。 fbdev将内存mmap至用户空间以至于可以直接访问。出于简化frmaebuffer编程的目的,显然这种模型是简单的,同时它也使得设备与平台无关 了。如果我们对编写驱动感兴趣的话,我们还需要了解更多关于具体显卡自身是如何工作的。

2.1 显示器

首先让我们来看看这 个最大却常被忽视的部件,显示器。从平面到LED,今天的显示器已是品种繁多。在琳琅满目的品种背后,最基本的原理都是一样的。基本上,显示器都是根据输 入线路提供的数据来持续构建图像。为了达到这个目的,每一帧时电子枪以zig-zag的方式在屏幕上扫描,覆盖整个屏幕的可视范围。这一切发生的太快以至 于人眼无法察觉。当然这也是我们所希望的。那电子枪是按何种线路行进的呢?所有显示器都通常采用从左至右然后在遇到右边界时快速跳回到下一左边界的方式。 从上至下也是这种方式,只是行进得较慢一些,因为大多数时间都花在了每行的从左至右扫描上。显然,为了构建稳定的图象,显示数据和电子枪的当前位置之间需 要同步。这就是你在你的显示器手册中看见的HSYNC及VSYNC所要做的事情。这两条电路(lines)会说,“嘿!该把电子枪移到左边了”或者“该把 电子枪移到上面了”。如此,一些系统把这些信息编码存储,比如把它放到绿色信号(channal)中,也就是所谓的sync on green,但原理并 没有变
。显示器所了解的显示模式仅仅是那些信号反馈的频率中所包含的信息(?)。这些频率称为水平频率和垂直频率(也就是刷新率),它决定了一幅 完整图象在一秒钟内被绘制的频度。所以显示器对色深、时钟、border一无所知。如果两种显示模式拥有同样的频率,那对显示器来说它们就是一样的。这就 是为什么不同的数据信息,如640x480x16及640x480x32并不存储在显示器中。显示器无法区分这些显示模式。在两个HSYNC之间,我们可 以得到RGB信号。

HSYNC __/~~~/______________________________________________/~~~/___ 
RGB ___________datadatadatadatadatadatadatadatadatad_____________ 
time    1    2 3                                     4    5 

点1,HSYNC脉冲开始涌起。此时电子枪会快速移至左侧。在这段时间内,RGB线路应该是黑屏的(射线关闭),否则,在电子枪移动的过程中会留下明显的痕迹,那样会很难看。

点2,HSYNC脉冲结束。这个阶段没有太多意思,因为此时你也搞不清射线是否已经在左边缘处了。关于点2唯一重要的是,1和2之间必须要有较长的持续时间,以便显示器检测出HSYNC信号。通常HSYNC脉冲可以做得很小(?)。

点1过后一段时间,射线将开始向右移动。到点3时,将开始实际显示数据。因此,点3可以用调整左边界的位置。如果发送数据前多等一会,左边界将会向右移动。

所有数据发送完毕后将达到点4。接下来将会送出HSYNC脉冲以开始新的一行,所以我们再次设置RGB线路为黑屏。点5时一个周期已经结束,将开始下一行。

2.2. 显卡

接 下来让我们站在显卡的角度来观察一下。显卡可以向显示器送出稳定的数据流,但有一点,显示器需要时间回扫,所以显卡需要在某些时刻插入“时延”。准确来说 是在点4和下一行开始之间(上图所示)。对于显卡来说,当它(向显示器)发送数据时,原始的坐标起点是点3。通常这会给modeline计算带来一些困 惑。


HSYNC __/~~~/_______________________________________________/~~~/___ 
RGB ____________datadatadatadatadatadatadatadatadatad_____________ 
time    1   2  3                                      4     5    6 
grc    SS  SE 0                                      W     SS  SE 

从显卡的角度来看(图中的grc),每一行从0处开始。在这之后,它将向外输出显存中的数据。有一个记数器用于限制每行输出的像素个数。也就是我们所说的显示模式中的宽度。在640x480标准VESA模式下,这个值是640像素。

现 在我们需要在右边留出一小段好让显示器准备我们接下来生成的SYNC脉冲。前面所说的记数器仍在运转(但不能向缓冲输出数据)直到我们到达点SS(同步开 始)。在640x480标准VGA模式下,该事件发生在664像素处(译注:假设有足够多的像素,在处理第664个像素时到达点SS。实际显存中的图形像 素宽还是640)。也就是,我们需要留出24个像素。

现在我们发出HSYNC告诉显示器将电子枪移至左侧。这一信号将保持到我们到达SE(同步结束)点。(VGA模式下是第760像素。也就是说有96个像素用于同步脉冲。这太长了,但VGA显示器的确工作得不快)。

我们还需要在左边留出位置,所以再次生成信号之前,我们需要等待下一个0的到来。标准VGA模式下,该事件发生在800像素处(左边界占据40像素)。此时,我们将设置计数器为0然后再启动。因为这个原因,这个点通常称为“终点”。

下面我们来看看如何通过在模式参数中修改这些数值来达到修改图像外观的目的。

将SS和SE合并将使得同步脉冲进入图像区域。我们假设把它们都放到左边,也就是减少一个起点。具体说就是缩短W-SS之间的距离并拉开0-SE的距离。结果是图像移到了右边。

如果改变W的位置会有什么后果?在右边界上你将看到额外的像素。在标准VGA模式下,边界通常都是很大的,所以显示类似648*486的分辨率通常都不会引发什么问题。你看不到之间的差别。

当然这也是有限度的:如果偏得太远,像素会产生在显示器的可视区之外,那就没有意义了,又或者会对回扫造成干扰,在CRT回扫射线中产生丑陋的条纹。

现在花点时间把剩下的术语过一下:

黑 屏开始BS以及黑屏结束BE。许多显卡可以在SE与0之间插入一个BE点。在这一点,RGB线路不再保持黑屏(避免对回扫造成干扰),但可以根据程序设置 为边界色。BS也是一样,它可以插在W与SS之间。如今通常都不再使用这一特性,因为我们拥有可调节的显示器,它允许把当前模式适应到显示器的物理限制 上。

在老式的显示器上,为了保证数据总是可见而使用了较大的边框。这些边框色总给人一种华而不实的感觉。

点时钟。像素输出到RGB线路的速率。通常它是显卡计时的基本单位。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值