日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux的帧缓冲设备

發布時間:2023/11/30 linux 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux的帧缓冲设备 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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 <linux/fb.h> int main() { int fbfd = 0;struct fb_var_screeninfo vinfo;struct fb_fix_screeninfo finfo;long int screensize = 0;/*打開設備文件*/fbfd = open("/dev/fb0", O_RDWR);/*取得屏幕相關參數*/ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo); ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo);/*計算屏幕緩沖區大小*/screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;/*映射屏幕緩沖區到用戶地址空間*/fbp=(char*)mmap(0,screensize,PROT_READ|PROT_WRITE,MAP_SHARED, fbfd, 0);/*下面可通過 fbp指針讀寫緩沖區*/……/*釋放緩沖區,關閉設備*/munmap(fbp, screensize);close(fbfd); }

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

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 <sys/mman.h>

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

int fd, off_t offset);

int munmap(void *start, size_t length);

參數:

start:映射區的開始地址。

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標志

SIGSEGV:試著向只讀區寫入

SIGBUS:試著訪問不屬于進程的內存區

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

總結

以上是生活随笔為你收集整理的Linux的帧缓冲设备的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。