Linux的幀緩衝裝置

2021-09-25 02:16:58 字數 4849 閱讀 8103

linux的幀緩衝裝置

幀緩衝(framebuffer)是 linux 為顯示裝置提供的乙個介面,把視訊記憶體抽象後的一種裝置,他允許上層應用程式在圖形模式下直接對顯示緩衝區進行讀寫操作。這種操作是抽象的,統一的。使用者不必關心物理視訊記憶體的位置、換頁機制等等具體細節。這些都是由framebuffer 裝置驅動來完成的。幀緩衝驅動的應用廣泛,在 linux 的桌面系統中,xwindow 伺服器就是利用幀緩衝進行視窗的繪製。尤其是通過幀緩衝可顯示漢字點陣,成為 linux漢化的唯一可行方案。

幀緩衝裝置對應的裝置檔案為/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:相當於讀/寫螢幕緩衝區。例如用 cp /dev/fb0 tmp 命令可將當前螢幕的內容拷貝到乙個檔案中,而命令 cp tmp > /dev/fb0 則將圖形檔案tmp顯示在螢幕上。

2.對映(map)操作:由於 linux 工作在保護模式,每個應用程式都有自己的虛擬位址空間,在應用程式中是不能直接訪問物理緩衝區位址的。為此,linux 在檔案操作 file_operations 結構中提供了 mmap 函式,可將檔案的內容對映到使用者空間。對於幀緩衝裝置,則可通過對映操作,可將螢幕緩衝區的物理位址對映到使用者空間的一段虛擬位址中,之後使用者就可以通過讀寫這段虛擬位址訪問螢幕緩衝區,在螢幕上繪圖了。

3.i/o控制:對於幀緩衝裝置,對裝置檔案的 ioctl操作可讀取/設定顯示裝置及螢幕的引數,如解析度,顯示顏色數,螢幕大小等等。ioctl 的操作是由底層的驅動程式來完成的。

在應用程式中,操作/dev/fb的一般步驟如下:

1.開啟/dev/fb裝置檔案。

2.用 ioctrl 操作取得當前顯示螢幕的引數,如螢幕解析度,每個畫素點的位元數。根據螢幕引數可計算螢幕緩衝

區的大小。

3.將螢幕緩衝區對映到使用者空間(mmap)。

4.對映後就可以直接讀寫螢幕緩衝區,進行繪圖和顯示了。

典型程式段如下:

------------------------

#include int main()

ioctl操作

ioctl(fbfd, fbioget_fscreeninfo, &finfo)

獲取fb_var_screeninfo結構的資訊,在linux/include/linux/fb.h定義。

ioctl(fbfd, fbioget_vscreeninfo, &vinfo)

獲取fb_fix_screeninfon結構的資訊。在linux/include/linux/fb.h定義。

fbfd為裝置檔案號。

-----------------------

mmap函式

功能描述:

mmap函式是unix/linux下的系統呼叫

mmap將乙個檔案或者其它物件對映進記憶體。檔案被對映到多個頁上,如果檔案的大小不是所有頁的大小之和,最後乙個頁不被使用的空間將會清零。munmap執行相反的操作,刪除特定位址區域的物件對映。

基於檔案的對映,在mmap和munmap執行過程的任何時刻,被對映檔案的st_atime可能被更新。如果st_atime欄位在前述的情況下沒有得到更新,首次對對映區的第乙個頁索引時會更新該字段的值。用prot_write 和 map_shared標誌建立起來的檔案對映,其st_ctime 和 st_mtime在對對映區寫入之後,但在msync()通過ms_sync 和 ms_async兩個標誌呼叫之前會被更新。

用法:

#include

void *mmap(void *start, size_t length, int prot, int flags,

int fd, off_t offset);

int munmap(void *start, size_t length);

引數:

length:對映區的長度。

prot:期望的記憶體保護標誌,不能與檔案的開啟模式衝突。是以下的某個值,可以通過or運算合理地組合在一起

prot_exec //頁內容可以被執行

prot_read //頁內容可以被讀取

prot_write //頁可以被寫入

prot_none //頁不可訪問

flags:指定對映物件的型別,對映選項和對映頁是否可以共享。它的值可以是乙個或者多個以下位的組合體

map_fixed //使用指定的對映起始位址,如果由start和len引數指定的記憶體區重疊於現存的對映空間,重疊部分將會被丟棄。如果指定的起始位址不可用,操作將會失敗。並且起始位址必須落在頁的邊界上。

map_shared //與其它所有對映這個物件的程序共享對映空間。對共享區的寫入,相當於輸出到檔案。直到msync()或者munmap()被呼叫,檔案實際上不會被更新。

map_private //建立乙個寫入時拷貝的私有對映。記憶體區域的寫入不會影響到原檔案。這個標誌和以上標誌是互斥的,只能使用其中乙個。

map_denywrite //這個標誌被忽略。

map_executable //同上

map_noreserve //不要為這個對映保留交換空間。當交換空間被保留,對對映區修改的可能會得到保證。當交換空間不被保留,同時記憶體不足,對對映區的修改會引起段違例訊號。

map_locked //鎖定對映區的頁面,從而防止頁面被交換出記憶體。

map_growsdown //用於堆疊,告訴核心vm系統,對映區可以向下擴充套件。

map_anonymous //匿名對映,對映區不與任何檔案關聯。

map_anon //map_anonymous的別稱,不再被使用。

map_file //相容標誌,被忽略。

map_32bit //將對映區放在程序位址空間的低2gb,map_fixed指定時會被忽略。當前這個標誌只在x86-64平台上得到支援。

map_populate //為檔案對映通過預讀的方式準備好頁表。隨後對對映區的訪問不會被頁違例阻塞。

map_nonblock //僅和map_populate一起使用時才有意義。不執行預讀,只為已存在於記憶體中的頁面建立頁表入口。

fd:有效的檔案描述詞。如果map_anonymous被設定,為了相容問題,其值應為-1。

offset:被對映物件內容的起點。

返回說明:

成功執行時,mmap()返回被對映區的指標,munmap()返回0。

失敗時,mmap()返回map_failed[其值為(void *)-1],munmap返回-1。errno被設為以下的某個值

eacces:訪問出錯

eagain:檔案已被鎖定,或者太多的記憶體已被鎖定

ebadf:fd不是有效的檔案描述詞

einval:乙個或者多個引數無效

enfile:已達到系統對開啟檔案的限制

enodev:指定檔案所在的檔案系統不支援記憶體對映

enomem:記憶體不足,或者程序已超出最大記憶體對映數量

eperm:權能不足,操作不允許

etxtbsy:已寫的方式開啟檔案,同時指定map_denywrite標誌

sigse**:試著向唯讀區寫入

sigbus:試著訪問不屬於程序的記憶體區

------------------------

關於Linux下的幀緩衝介紹

幀緩衝在各種顯示卡硬體各有不同,如ati rage128提供了自己的幀緩衝,cirrus logic,matrox,powervr 2,都有自己的幀緩衝,tga,vesa,是兩種幀緩衝裝置標準,vesa由於被大多數現代顯示卡所具有,所以使用的較為廣泛。不同的幀緩衝裝置需要在核心編譯時使用不同的驅動。...

幀緩衝儲存器

幀緩衝儲存器 frame buffer 簡稱幀快取或視訊記憶體,它是螢幕所顯示畫面的乙個直接映象,又稱為位對映圖 bit map 或光柵。幀快取的每一儲存單元對應螢幕上的乙個畫素,整個幀快取對應一幀影象。幀緩衝是linux為顯示裝置提供的乙個介面,把視訊記憶體抽象後的一種裝置,他允許上層應用程式在圖...

幀緩衝驅動程式設計

視訊記憶體 幀緩衝 顯示快取 framebuffer從本質上講是圖形裝置的硬體抽象。對開發者而言,framebuffer是一塊顯示快取,往顯示快取中寫入特定格式的資料就意味著向螢幕輸出內容。通過不斷的向frame buffer中寫入資料,顯示控制器就自動的從frame buffer中取資料並顯示出來...