幀緩衝裝置¶
上次修訂時間:2001 年 5 月 10 日
0. 介紹¶
幀緩衝裝置為圖形硬體提供了一個抽象。它代表了某些影片硬體的幀緩衝,並允許應用程式軟體透過定義良好的介面訪問圖形硬體,因此軟體不需要了解任何關於底層(硬體暫存器)的東西。
該裝置透過特殊的裝置節點訪問,通常位於 /dev 目錄中,例如 /dev/fb*。
1. /dev/fb* 的使用者視角¶
從使用者的角度來看,幀緩衝裝置看起來就像 /dev 中的任何其他裝置。它是一個主裝置號為 29 的字元裝置;次裝置號指定幀緩衝編號。
按照慣例,使用以下裝置節點(數字表示裝置次裝置號)
0 = /dev/fb0 First frame buffer
1 = /dev/fb1 Second frame buffer
...
31 = /dev/fb31 32nd frame buffer
為了向後相容,您可能需要建立以下符號連結
/dev/fb0current -> fb0
/dev/fb1current -> fb1
等等...
幀緩衝裝置也是普通記憶體裝置,這意味著您可以讀取和寫入它們的內容。 例如,您可以透過以下方式製作螢幕快照
cp /dev/fb0 myfile
也可以同時存在多個幀緩衝,例如,如果除了內建硬體之外,您還有一張顯示卡。 相應的幀緩衝裝置(/dev/fb0 和 /dev/fb1 等)獨立工作。
使用幀緩衝裝置的應用程式軟體(例如 X 伺服器)預設將使用 /dev/fb0(較舊的軟體使用 /dev/fb0current)。 您可以透過將環境變數 $FRAMEBUFFER 設定為幀緩衝裝置的路徑名來指定替代幀緩衝裝置,例如(對於 sh/bash 使用者)
export FRAMEBUFFER=/dev/fb1
或(對於 csh 使用者)
setenv FRAMEBUFFER /dev/fb1
此後,X 伺服器將使用第二個幀緩衝。
2. /dev/fb* 的程式設計師視角¶
如您所知,幀緩衝裝置是像 /dev/mem 這樣的記憶體裝置,它具有相同的功能。 您可以讀取它、寫入它、定址到其中的某個位置並對其進行 mmap()(主要用法)。 區別僅在於特殊檔案中出現的記憶體不是整個記憶體,而是某些影片硬體的幀緩衝。
/dev/fb* 還允許對其進行多個 ioctl 操作,透過這些操作可以查詢和設定有關硬體的許多資訊。 顏色對映處理也透過 ioctl 進行。 檢視 <linux/fb.h> 以獲取有關存在的 ioctl 以及它們所作用的資料結構的更多資訊。 這是一個簡要概述
您可以請求有關硬體的不可更改的資訊,例如名稱、螢幕記憶體的組織方式(平面、壓縮畫素...)以及螢幕記憶體的地址和長度。
您可以請求和更改有關硬體的可變資訊,例如可見和虛擬幾何體、深度、顏色對映格式、時序等。 如果您嘗試更改該資訊,驅動程式可能會舍入一些值以滿足硬體的功能(如果不可能,則返回 EINVAL)。
您可以獲取和設定顏色對映的一部分。 通訊使用每個顏色部分(紅色、綠色、藍色、透明度)16 位來完成,以支援所有現有硬體。 驅動程式會完成所有需要的計算,以將其應用於硬體(向下舍入到更少的位,可能會丟棄透明度)。
所有這些硬體抽象使得應用程式的實現更加容易和更具可移植性。 例如,X 伺服器完全在 /dev/fb* 上執行,因此不需要知道例如具體硬體的顏色暫存器是如何組織的。 XF68_FBDev 是用於點陣圖、非加速影片硬體的通用 X 伺服器。 必須構建到應用程式中的唯一東西是螢幕組織(位平面或塊狀畫素等),因為它直接在幀緩衝影像資料上執行。
將來計劃將圖形卡等幀緩衝驅動程式實現為執行時載入的核心模組。 這樣的驅動程式只需呼叫 register_framebuffer() 並提供一些函式。 獨立於核心編寫和分發此類驅動程式將節省很多麻煩...
3. 幀緩衝解析度維護¶
幀緩衝解析度使用實用程式 fbset 維護。 它可以更改幀緩衝裝置的影片模式屬性。 它的主要用途是更改當前的影片模式,例如在您的 /etc/rc.* 或 /etc/init.d/* 檔案之一中啟動期間。
Fbset 使用儲存在配置檔案中的影片模式資料庫,因此您可以輕鬆新增自己的模式並使用簡單的識別符號引用它們。
4. X 伺服器¶
X 伺服器 (XF68_FBDev) 是幀緩衝裝置最著名的應用程式。 從 XFree86 release 3.2 開始,X 伺服器是 XFree86 的一部分,並具有 2 種模式
如果 /etc/XF86Config 檔案中 fbdev 驅動程式的 Display 小節包含
Modes "default"行,X 伺服器將使用上述方案,即它將在 /dev/fb0(如果設定了 $FRAMEBUFFER)確定的解析度下啟動。 您仍然必須指定顏色深度(使用 Depth 關鍵字)和虛擬解析度(使用 Virtual 關鍵字)。 這是 XFree86 提供的配置檔案的預設設定。 它是最簡單的配置,但有一些限制。
因此,也可以在 /etc/XF86Config 檔案中指定解析度。 這允許在保持相同虛擬桌面大小的同時進行動態解析度切換。 使用的幀緩衝裝置仍然是 /dev/fb0current(或 $FRAMEBUFFER),但可用解析度現在由 /etc/XF86Config 定義。 缺點是您必須以不同的格式指定時序(但 fbset -x 可能會有所幫助)。
要調整影片模式,您可以使用 fbset 或 xvidtune。 請注意,xvidtune 與 XF68_FBDev 不能 100% 相容:報告的時鐘值始終不正確。
5. 影片模式時序¶
監視器透過使用電子束在螢幕上繪製圖像(彩色型號使用 3 個電子束,單色監視器使用 1 個電子束)。 螢幕正面覆蓋著彩色熒光粉(畫素)的圖案。 如果熒光粉被電子擊中,它會發射光子,從而變得可見。
電子束從左到右,從螢幕頂部到底部繪製水平線(掃描線)。 透過修改電子束的強度,可以顯示具有各種顏色和強度的畫素。
在每條掃描線之後,電子束必須移回螢幕的左側並移動到下一行:這稱為水平回掃。 在繪製完整個螢幕(幀)後,光束移回左上角:這稱為垂直回掃。 在水平和垂直回掃期間,電子束關閉(消隱)。
電子束繪製畫素的速度由圖形板中的點時鐘決定。 對於例如 28.37516 MHz(每秒數百萬個週期)的點時鐘,每個畫素的長度為 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) = 58.815 Hz
這意味著螢幕資料每秒重新整理約 59 次。 為了獲得沒有可見閃爍的穩定影像,VESA 建議垂直掃描速率至少為 72 Hz。 但感知到的閃爍非常依賴於人:有些人可以毫無問題地使用 50 Hz,而如果低於 80 Hz 我會注意到。
由於監視器不知道何時開始新的掃描線,因此圖形板將為每條掃描線提供同步脈衝(水平同步或 hsync)。 同樣,它為每個新幀提供同步脈衝(垂直同步或 vsync)。 影像在螢幕上的位置受到同步脈衝發生的時刻的影響。
下圖總結了所有時序。 水平回掃時間是左邊距、右邊距和 hsync 長度的總和,而垂直回掃時間是上邊距、下邊距和 vsync 長度的總和
+----------+---------------------------------------------+----------+-------+
| | ↑ | | |
| | |upper_margin | | |
| | ↓ | | |
+----------###############################################----------+-------+
| # ↑ # | |
| # | # | |
| # | # | |
| # | # | |
| left # | # right | hsync |
| margin # | xres # margin | len |
|<-------->#<---------------+--------------------------->#<-------->|<----->|
| # | # | |
| # | # | |
| # | # | |
| # |yres # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # ↓ # | |
+----------###############################################----------+-------+
| | ↑ | | |
| | |lower_margin | | |
| | ↓ | | |
+----------+---------------------------------------------+----------+-------+
| | ↑ | | |
| | |vsync_len | | |
| | ↓ | | |
+----------+---------------------------------------------+----------+-------+
幀緩衝裝置期望所有水平時序都以點時鐘數(以皮秒為單位,1E-12 秒)表示,而垂直時序以掃描線數表示。
6. 將 XFree86 時序值轉換為幀緩衝裝置時序¶
XFree86 模式行由以下欄位組成
"800x600" 50 800 856 976 1040 600 637 643 666
< name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL
幀緩衝裝置使用以下欄位
pixclock:畫素時鐘,單位為 ps(皮秒)
left_margin:從同步到圖片的間隔
right_margin:從圖片到同步的間隔
upper_margin:從同步到圖片的間隔
lower_margin:從圖片到同步的間隔
hsync_len:水平同步的長度
vsync_len:垂直同步的長度
畫素時鐘
xfree:單位為 MHz
fb:單位為皮秒 (ps)
pixclock = 1000000 / DCF
水平時序
left_margin = HFL - SH2
right_margin = SH1 - HR
hsync_len = SH2 - SH1
垂直時序
upper_margin = VFL - SV2
lower_margin = SV1 - VR
vsync_len = SV2 - SV1
可以在 XFree86 原始碼樹的“xc/programs/Xserver/hw/xfree86/doc/modeDB.txt”下找到 VESA 時序的良好示例。
7. 參考¶
有關幀緩衝裝置及其應用的更多具體資訊,請訪問 Linux-fbdev 網站
以及以下文件
fbset 的手冊頁:fbset(8), fb.modes(5)
XFree86 的手冊頁:XF68_FBDev(1), XF86Config(4/5)
強大的核心原始碼
linux/drivers/video/
linux/include/linux/fb.h
linux/include/video/
8. 郵件列表¶
kernel.org 上有一個與幀緩衝裝置相關的郵件列表:linux-fbdev@vger.kernel.org。
將您的 Web 瀏覽器指向 http://sourceforge.net/projects/linux-fbdev/ 以獲取訂閱資訊和存檔瀏覽。
9. 下載¶
所有必要的檔案都可以在
及其映象上找到。
fbset 的最新版本可以在
找到。
10. 鳴謝¶
本自述檔案由 Geert Uytterhoeven 編寫,部分基於 Roman Hodek 和 Martin Schaller 的原始 X-framebuffer.README。 第 6 節由 Frank Neumann 提供。