在后續(xù)的幾篇里面會(huì)詳細(xì)介紹如何編寫一個(gè)顯卡的驅(qū)動(dòng)程序。 framebuffer device在內(nèi)核里面作為顯卡驅(qū)動(dòng)模型,許多函數(shù)和數(shù)據(jù)結(jié)構(gòu)都是特定,正是這些特定的東西為我們的編程提供了方便。 要開發(fā)frame buffer device驅(qū)動(dòng),你應(yīng)該閱讀Source\Source\Documentation\fb下面的說(shuō)明文件,三個(gè)重要文件00-INDEX,framebuffer.txt,internals.txt,其他文件都是針對(duì)具體顯卡芯片的說(shuō)明了。 文件00-INDEX譯文
文檔/documentation/fb的索引文件。如果你對(duì)frame buffer設(shè)備有什么想法,mail:Geert Uytterhoeven <geert@linux-m68k.org> 00-index 這個(gè)文件 framebuffer.txt--- frame buffer 設(shè)備介紹 internals.txt----frame buffer設(shè)備內(nèi)部快速瀏覽 modedb.txt----關(guān)于視頻模式的資料 aty128fb.txt----關(guān)于ATI Rage128顯卡的frame buffer設(shè)備 clgenfb.txt-----關(guān)于Cirrus Logic的顯卡 matroxfb.txt----關(guān)于Matrox的顯卡 pvr2fb.txt----關(guān)于PowerVR 2的顯卡 tgafb.txt----關(guān)于TGA(DECChip 21030)顯卡 vesafb.txt----關(guān)于VESA顯卡 幀緩沖設(shè)備(framebuffer.txt譯文) 維護(hù): Geert Uytterhoeven <geert@linux-m68k.org> 最后校正: May 10, 2001 翻譯:good02xaut@hotmail.com
0.介紹 幀緩沖設(shè)備提供了顯卡的抽象描述。他同時(shí)代表了顯卡上的顯存,應(yīng)用程序通過(guò)定義好的接口可以訪問顯卡,而不需要知道底層的任何操作。 該設(shè)備使用特殊的設(shè)備節(jié)點(diǎn),通常位于/dev目錄,如/dev/fb*. 1.用戶角度的/dev/fb* 從用戶的角度看,幀緩沖設(shè)備和其他位于/dev下面的設(shè)備類似。他是一個(gè)字符設(shè)備,通常 主設(shè)備號(hào)是29,次設(shè)備號(hào)定義幀緩沖的個(gè)數(shù)。 通常,使用如下方式(前面的數(shù)字代碼次設(shè)備號(hào)) 0 = /dev/fb0 First frame buffer 1 = /dev/fb1 Second frame buffer ... 31 = /dev/fb31 32nd frame buffer 考慮到向下兼容,你可以創(chuàng)建符號(hào)鏈接: /dev/fb0current -> fb0 /dev/fb1current -> fb1
and so on... 幀緩沖設(shè)備也是一種普通的內(nèi)存設(shè)備,你可以讀寫其內(nèi)容。例如,對(duì)屏幕抓屏: cp /dev/fb0 myfile
你也可以同時(shí)有多個(gè)顯示設(shè)備,例如你的主板上出了內(nèi)置的顯卡還有另一獨(dú)立的 顯卡。對(duì)應(yīng)的幀緩沖設(shè)備(/dev/fb0 and /dev/fb1 etc.)可以獨(dú)立工作。 應(yīng)用程序如 X server一般使用/dev/fb0作為默認(rèn)的顯示幀緩沖區(qū)。你可以自定 把某個(gè)設(shè)備作為默認(rèn)的幀緩沖設(shè)備,設(shè)置$FRAMEBUFFER環(huán)境變量即可。在sh/bash: export FRAMEBUFFER=/dev/fb1
在csh中:
setenv FRAMEBUFFER /dev/fb1 設(shè)定后,X server將使用第二個(gè)幀緩沖區(qū)設(shè)備。 2.程序員角度看/dev/fb* 正如你所知,一個(gè)幀緩沖設(shè)備和內(nèi)存設(shè)備類似/dev/mem,并且有許多共性。你可以 read,write,seek以及mmap()。不同僅僅是幀緩沖的內(nèi)存不是所有的內(nèi)存區(qū),而是顯卡 專用的那部分內(nèi)存。 /dev/fb*也允許盡心ioctl操作,通過(guò)ioctl可以讀取或設(shè)定設(shè)備參數(shù)。顏色映射表 也是通過(guò)Ioctl設(shè)定。查看<linux/fb.h>就知道有多少ioctl應(yīng)用以及相關(guān)數(shù)據(jù)結(jié)構(gòu)。 這里給出摘要: - 你可以獲取設(shè)備一些不變的信息,如設(shè)備名,屏幕的組織(平面,象素,...)對(duì)應(yīng)內(nèi)存區(qū) 的長(zhǎng)度和起始地址。
- 也可以獲取能夠發(fā)生變化的信息,例如位深,顏色格式,時(shí)序等。如果你改變這些值, 驅(qū)動(dòng)程序?qū)?duì)值進(jìn)行優(yōu)化,以滿足設(shè)備特性(返回EINVAL,如果你的設(shè)定,設(shè)備不支持)
- 你也可以獲取或設(shè)定部分顏色表。 所有這些特性讓應(yīng)用程序十分容易的使用設(shè)備。X server可以使用/dev/fb*而不需知道硬件 的寄存器是如何組織的。 XF68_FBDev是一個(gè)用于位映射(單色)X server,唯一要做的就是 在應(yīng)用程序在相應(yīng)的位置設(shè)定是否顯示。 在新內(nèi)核中,幀緩沖設(shè)備可以工作于模塊中,允許動(dòng)態(tài)加載。這類驅(qū)動(dòng)必須調(diào)用 register_framebuffer()在系統(tǒng)中注冊(cè)。使用模塊更方便! 3.幀緩沖分辨率設(shè)定 幀緩沖的分辨率可以用工具fbset設(shè)定。他可以改變視頻設(shè)備的顯示模式。主要就是 改變當(dāng)前視頻模式,如在啟動(dòng)過(guò)程中,在/etc/rc.* 或 /etc/init.d/* 文件中調(diào)用, 可以把視頻模式從單色顯示變成真彩. fbset使用存儲(chǔ)在配置文件中的視頻模式數(shù)據(jù)表,你可以在文件中增加自己需要的顯示模式。 4.X Server X server (XF68_FBDev)是對(duì)幀緩沖設(shè)備的最主要應(yīng)用。從XFree86 3.2后,X server就是 XFree86 的一部分了,有2個(gè)工作模式: - 在/etc/XF86Config文件中,如果`Display"段關(guān)于 `fbdev"的配置:
Modes "default"
X server 將使用前面討論的,從環(huán)境變量$FRAMEBUFFER獲取當(dāng)前幀緩沖設(shè)備. 你也可以設(shè)定顏色位深,使用Depth關(guān)鍵字,使用Virtual設(shè)定虛擬分辨率。這也是 默認(rèn)設(shè)置。
- 然而你也可以通過(guò)設(shè)定/etc/XF86Config,改變分辨率。這樣有很多靈活性,唯一的 不足就是你必須設(shè)定刷新頻率。可以用fbset -x
通過(guò)fbset或xvidtune切換顯示模式。 5.視頻模式頻率 CRT顯示器是用3個(gè)電子槍轟擊磷粉完成顏色的顯示的。 電子槍從左到右的水平掃描,并從上至下的垂直掃描。通過(guò)改變槍的電壓,所顯示的顏色 可以不同。 當(dāng)電子槍完成一行掃描重新回到下一行的開始,被稱作“水平折回”。當(dāng)一屏幕全部 掃描完畢,電子槍將回到最左上腳,被成為“垂直折回”。在折回的途中電子槍是關(guān)閉的。 電子槍打點(diǎn)的移動(dòng)速度取決于點(diǎn)時(shí)鐘。如果點(diǎn)時(shí)鐘是28.37516 MHz,打一個(gè)點(diǎn)需要 35242 ps。 1/(28.37516E6 Hz) = 35.242E-9 s 如果屏幕分辨率是640x480,那么一行的時(shí)間是: 640*35.242E-9 s = 22.555E-6 s 然而水平折回也是需要時(shí)間的,通常272個(gè)打點(diǎn)時(shí)間,因此一行總共需要: (640+272)*35.242E-9 s = 32.141E-6 s 我們就認(rèn)為水平掃描的頻率是31KHz: 1/(32.141E-6 s) = 31.113E3 Hz 一屏幕含有480行,加上垂直折回時(shí)間49,一屏所需的時(shí)間: (480+49)*32.141E-6 s = 17.002E-3 s 我們就認(rèn)為垂直掃描的頻率是59Hz: 1/(17.002E-3 s) = 58.815 Hz 這也意味著屏幕數(shù)據(jù)每秒鐘刷新59次。為了得到穩(wěn)定的圖像顯示效果,VESA垂直掃描 頻率不低于72Hz。但是也因人而異,有些人50Hz感覺不到任何問題,有些至少在 80Hz以上才可以。 由于顯示器不知道什么時(shí)候新行開始掃描,顯卡為每一行掃描提供水平同步信號(hào)。 類似的,他也為每一幀顯示提供垂直同步信號(hào)。圖像在屏幕上點(diǎn)的位置取決于這些 同步信號(hào)的發(fā)生時(shí)刻。 下圖給出了所有時(shí)序的概要。水平折回的時(shí)間就是左邊空白+右邊空白+水平同步長(zhǎng)度。 垂直折回的時(shí)間就是上空白+下空白+垂直同步長(zhǎng)。 +----------+---------------------------------------------+----------+-------+ | | ^ | | | | | |upper_margin | | | | | ? | | | +----------###############################################----------+-------+ | # ^ # | | | # | # | | | # | # | | | # | # | | | left # | # right | hsync | | margin # | xres # margin | len | |<-------->#<---------------+--------------------------->#<-------->|<----->| | # | # | | | # | # | | | # | # | | | # |yres # | | | # | # | | | # | # | | | # | # | | | # | # | | | # | # | | | # | # | | | # | # | | | # | # | | | # ? # | | +----------###############################################----------+-------+ | | ^ | | | | | |lower_margin | | | | | ? | | | +----------+---------------------------------------------+----------+-------+ | | ^ | | | | | |vsync_len | | | | | ? | | | +----------+---------------------------------------------+----------+-------+ 6.把XFree86時(shí)序變成frame buffer device時(shí)序 典型的顯示模式: "800x600" 50 800 856 976 1040 600 637 643 666 < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL 而幀緩沖設(shè)備使用下面的參數(shù): - pixclock: 點(diǎn)時(shí)鐘 in ps (pico seconds) - left_margin: time from sync to picture - right_margin: time from picture to sync - upper_margin: time from sync to picture - lower_margin: time from picture to sync - hsync_len: length of horizontal sync - vsync_len: length of vertical sync 1) Pixelclock: xfree: in MHz fb: in picoseconds (ps)
pixclock = 1000000 / DCF
2) horizontal timings: left_margin = HFL - SH2 right_margin = SH1 - HR hsync_len = SH2 - SH1
3) vertical timings: upper_margin = VFL - SV2 lower_margin = SV1 - VR vsync_len = SV2 - SV1 更好的VESA的例子可以在XFree86的源碼中找到,
|