1. 程式人生 > >一、 FrameBuffer 原理、實現與應用 寫屏

一、 FrameBuffer 原理、實現與應用 寫屏

 一、FrameBuffer的原理

   FrameBuffer 是出現在 2.2.xx 核心當中的一種驅動程式介面。

   Linux是工作在保護模式下,所以使用者態程序是無法象DOS那樣使用顯示卡BIOS裡提供的中斷呼叫來實現直接寫屏,Linux抽象出FrameBuffer這個裝置來供使用者態程序實現直接寫屏Framebuffer機制模仿顯示卡的功能,將顯示卡硬體結構抽象掉,可以通過Framebuffer的讀寫直接對視訊記憶體進行操作。使用者可以將Framebuffer看成是顯示記憶體的一個映像,將其對映到程序地址空間之後,就可以直接進行讀寫操作,而寫操作可以立即反應在螢幕上。這種操作是抽象的,統一的。使用者不必關心物理視訊記憶體的位置、換頁機制等等具體細節。這些都是由Framebuffer裝置驅動來完成的。

    但Framebuffer本身不具備任何運算資料的能力,就只好比是一個暫時存放水的水池.CPU將運算後的結果放到這個水池,水池再將結果流到顯示器.中間不會對資料做處理. 應用程式也可以直接讀寫這個水池的內容.在這種機制下,儘管Framebuffer需要真正的顯示卡驅動的支援,但所有顯示任務都有CPU完成,因此CPU負擔很重.

framebuffer的裝置檔案一般是 /dev/fb0、/dev/fb1 等等。

可以用命令: #ddif=/dev/zero of=/dev/fb 清空螢幕.

如果顯示模式是1024x768-8 位色,用命令:$ ddif=/dev/zero of=/dev/fb0 bs=1024 count=768 清空螢幕;

用命令: #ddif=/dev/fb of=fbfile  可以將fb中的內容儲存下來;

可以重新寫回螢幕: #ddif=fbfile of=/dev/fb;

在使用Framebuffer時,Linux是將顯示卡置於圖形模式下的.

    在應用程式中,一般通過將FrameBuffer 裝置對映到程序地址空間的方式使用,比如下面的程式就開啟 /dev/fb0 裝置,並通過 mmap 系統呼叫進行地址對映,隨後用 memset 將螢幕清空(這裡假設顯示模式是1024x768-8 位色模式,線性記憶體模式):

int fb;

unsigned char* fb_mem;

fb = open ("/dev/fb0", O_RDWR);

fb_mem = mmap (NULL, 1024*768,PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);

memset (fb_mem, 0, 1024*768);

   FrameBuffer 裝置還提供了若干 ioctl 命令,通過這些命令,可以獲得顯示裝置的一些固定資訊(比如顯示記憶體大小)、與顯示模式相關的可變資訊(比如解析度、象素結構、每掃描線的位元組寬度),以及偽彩色模式下的調色盤資訊等等。

    通過FrameBuffer 裝置,還可以獲得當前核心所支援的加速顯示卡的型別(通過固定資訊得到),這種型別通常是和特定顯示晶片相關的。比如目前最新的核心(2.4.9)中,就包含有對 S3、Matrox、nVidia、3Dfx 等等流行顯示晶片的加速支援。在獲得了加速晶片型別之後,應用程式就可以將 PCI 裝置的記憶體I/O(memio)對映到程序的地址空間。這些 memio 一般是用來控制顯示卡的暫存器,通過對這些暫存器的操作,應用程式就可以控制特定顯示卡的加速功能。

   PCI 裝置可以將自己的控制暫存器對映到實體記憶體空間,而後,對這些控制暫存器的訪問,給變成了對實體記憶體的訪問。因此,這些暫存器又被稱為"memio"。一旦被對映到實體記憶體,Linux 的普通程序就可以通過 mmap 將這些記憶體 I/O 對映到程序地址空間,這樣就可以直接訪問這些暫存器了。

    當然,因為不同的顯示晶片具有不同的加速能力,對memio 的使用和定義也各自不同,這時,就需要針對加速晶片的不同型別來編寫實現不同的加速功能。比如大多數晶片都提供了對矩形填充的硬體加速支援,但不同的晶片實現方式不同,這時,就需要針對不同的晶片型別編寫不同的用來完成填充矩形的函式。

   FrameBuffer 只是一個提供顯示記憶體和顯示晶片暫存器從實體記憶體對映到程序地址空間中的裝置。所以,對於應用程式而言,如果希望在 FrameBuffer 之上進行圖形程式設計,還需要自己動手完成其他許多工作。

二、FrameBuffer在Linux中的實現和機制

Framebuffer對應的原始檔在linux/drivers/video/目錄下。總的抽象裝置檔案為fbcon.c,在這個目錄下還有與各種顯示卡驅動相關的原始檔。

(一)、分析Framebuffer裝置驅動

    需要特別提出的是在INTEL平臺上,老式的VESA1.2 卡,如CGA/EGA卡,是不能支援Framebuffer的,因為Framebuffer要求顯示卡支援線性幀緩衝,即CPU可以訪問顯緩衝中的每一位,但是VESA 1.2 卡只能允許CPU一次訪問64K的地址空間。

FrameBuffer裝置驅動基於如下兩個檔案:

1) linux/include/linux/fb.h

2) linux/drivers/video/fbmem.c

下面分析這兩個檔案。

1、fb.h

   幾乎主要的結構都是在這個中檔案定義的。這些結構包括:

1)fb_var_screeninfo

   這個結構描述了顯示卡的特性

struct fb_var_screeninfo

{

__u32 xres; /* visible resolution */

__u32 yres;

__u32 xres_virtual; /* virtual resolution*/

__u32 yres_virtual;

__u32 xoffset; /* offset from virtual tovisible resolution */

__u32 yoffset;

__u32 bits_per_pixel; /* guess what */

__u32 grayscale; /* != 0 Gray levelsinstead of colors */

struct fb_bitfield red; /* bitfield in fbmem if true color, */

struct fb_bitfield green; /* else onlylength is significant */

struct fb_bitfield blue;

struct fb_bitfield transp; /* transparency*/

__u32 nonstd; /* != 0 Non standard pixelformat */

__u32 activate; /* see FB_ACTIVATE_* */

__u32 height; /* height of picture in mm */

__u32 width; /* width of picture in mm */

__u32 accel_flags; /* acceleration flags(hints) */

/* Timing: All values in pixclocks, exceptpixclock (of course) */

__u32 pixclock; /* pixel clock in ps (picoseconds) */

__u32 left_margin; /* time from sync topicture */

__u32 right_margin; /* time from picture tosync */

__u32 upper_margin; /* time from sync topicture */

__u32 lower_margin;

__u32 hsync_len; /* length of horizontalsync */

__u32 vsync_len; /* length of vertical sync*/

__u32 sync; /* see FB_SYNC_* */

__u32 vmode; /* see FB_VMODE_* */

__u32 reserved[6]; /* Reserved for futurecompatibility */

};

2) fb_fix_screeninfon

這個結構在顯示卡被設定模式後建立,它描述顯示卡的屬性,並且系統執行時不能被修改;比如FrameBuffer記憶體的起始地址。它依賴於被設定的模式,當一個模式被設定後,記憶體資訊由顯示卡硬體給出,記憶體的位置等資訊就不可以修改。

struct fb_fix_screeninfo {

char id[16]; /* identification string eg"TT Builtin" */

unsigned long smem_start; /* Start of framebuffer mem */

/* (physical address) */

__u32 smem_len; /* Length of frame buffermem */

__u32 type; /* see FB_TYPE_* */

__u32 type_aux; /* Interleave forinterleaved Planes */

__u32 visual; /* see FB_VISUAL_* */

__u16 xpanstep; /* zero if no hardwarepanning */

__u16 ypanstep; /* zero if no hardwarepanning */

__u16 ywrapstep; /* zero if no hardwareywrap */

__u32 line_length; /* length of a line inbytes */

unsigned long mmio_start; /* Start ofMemory Mapped I/O */

/* (physical address) */

__u32 mmio_len; /* Length of Memory MappedI/O */

__u32 accel; /* Type of accelerationavailable */

__u16 reserved[3]; /* Reserved for futurecompatibility */

};

3) fb_cmap

描述裝置無關的顏色對映資訊。可以通過FBIOGETCMAP和 FBIOPUTCMAP 對應的ioctl操作設定或獲取顏色對映資訊.

struct fb_cmap {

__u32 start; /* First entry */

__u32 len; /* Number of entries */

__u16 *red; /* Red values */

__u16 *green;

__u16 *blue;

__u16 *transp; /* transparency, can be NULL*/

};

4) fb_info

定義當顯示卡的當前狀態;fb_info結構僅在核心中可見,在這個結構中有一個fb_ops指標,指向驅動裝置工作所需的函式集。

struct fb_info {

char modename[40]; /* default video mode */

kdev_t node;

int flags;

int open; /* Has this been open already ?*/

#define FBINFO_FLAG_MODULE 1 /* Low-leveldriver is a module */

struct fb_var_screeninfo var; /* Currentvar */

struct fb_fix_screeninfo fix; /* Currentfix */

struct fb_monspecs monspecs; /* CurrentMonitor specs */

struct fb_cmap cmap; /* Current cmap */

struct fb_ops *fbops;

char *screen_base; /* Virtual address */

struct display *disp; /* initial displayvariable */

struct vc_data *display_fg; /* Consolevisible on this display */

char fontname[40]; /* default font name */

devfs_handle_t devfs_handle; /* Devfshandle for new name */

devfs_handle_t devfs_lhandle; /* Devfshandle for compat. symlink */

int (*changevar)(int); /* tell console varhas changed */

int (*switch_con)(int, struct fb_info*);

/* tell fb to switch consoles */

int (*updatevar)(int, struct fb_info*);

/* tell fb to update the vars */

void (*blank)(int, struct fb_info*); /*tell fb to (un)blank the screen */

/* arg = 0: unblank */

/* arg > 0: VESA level (arg-1) */

void *pseudo_palette; /* Fake palette of 16colors and

the cursor's color for non

palette mode */

/* From here on everything is devicedependent */

void *par;

};

5) struct fb_ops

使用者應用可以使用ioctl()系統呼叫來操作裝置,這個結構就是用一支援ioctl()的這些操作的。

struct fb_ops {

/* open/release and usage marking */

struct module *owner;

int (*fb_open)(struct fb_info *info, intuser);

int (*fb_release)(struct fb_info *info, intuser);

/* get non settable parameters */

int (*fb_get_fix)(struct fb_fix_screeninfo*fix, int con,

struct fb_info *info);

/* get settable parameters */

int (*fb_get_var)(struct fb_var_screeninfo*var, int con,

struct fb_info *info);

/* set settable parameters */

int (*fb_set_var)(struct fb_var_screeninfo*var, int con,

struct fb_info *info);

/* get colormap */

int (*fb_get_cmap)(struct fb_cmap *cmap,int kspc, int con,

struct fb_info *info);

/* set colormap */

int (*fb_set_cmap)(struct fb_cmap *cmap,int kspc, int con,

struct fb_info *info);

/* pan display (optional) */

int (*fb_pan_display)(structfb_var_screeninfo *var, int con,

struct fb_info *info);

/* perform fb specific ioctl (optional) */

int (*fb_ioctl)(struct inode *inode, structfile *file, unsigned int cmd,

unsigned long arg, int con, struct fb_info*info);

/* perform fb specific mmap */

int (*fb_mmap)(struct fb_info *info, structfile *file, struct vm_area_struct *vma);

/* switch to/from raster image mode */

int (*fb_rasterimg)(struct fb_info *info,int start);

};

6) structuremap

struct fb_info_gen | struct fb_info |fb_var_screeninfo

| | fb_fix_screeninfo

| | fb_cmap

| | modename[40]

| | fb_ops ---|--->ops on var

| | ... | fb_open

| | | fb_release

| | | fb_ioctl

| | | fb_mmap

| struct fbgen_hwswitch -|-> detect

| | encode_fix

| | encode_var

| | decode_fix

| | decode_var

| | get_var

| | set_var

| | getcolreg

| | setcolreg

| | pan_display

| | blank

| | set_disp

[編排有點困難,第一行的第一條豎線和下面的第一列豎線對齊,第一行的第二條豎線和下面的第二列豎線對齊就可以了]

這個結構fbgen_hwswitch抽象了硬體的操作.雖然它不是必需的,但有時候很有用.

2、 fbmem.c

fbmem.c 處於Framebuffer裝置驅動技術的中心位置.它為上層應用程式提供系統呼叫也為下一層的特定硬體驅動提供介面;那些底層硬體驅動需要用到這兒的介面來向系統核心註冊它們自己. fbmem.c 為所有支援FrameBuffer的裝置驅動提供了通用的介面,避免重複工作.

1) 全域性變數

struct fb_info *registered_fb[FB_MAX];

int num_registered_fb;

這兩變數記錄了所有fb_info 結構的例項,fb_info 結構描述顯示卡的當前狀態,所有裝置對應的fb_info 結構都儲存在這個陣列中,當一個FrameBuffer裝置驅動向系統註冊自己時,其對應的fb_info 結構就會新增到這個結構中,同時num_registered_fb 為自動加1.

static struct {

const char *name;

int (*init)(void);

int (*setup)(void);

} fb_drivers[] __initdata= { ....};

如果FrameBuffer裝置被靜態連結到核心,其對應的入口就會新增到這個表中;如果是動態載入的,即使用insmod/rmmod,就不需要關心這個表。

static struct file_operations fb_ops ={

owner: THIS_MODULE,

read: fb_read,

write: fb_write,

ioctl: fb_ioctl,

mmap: fb_mmap,

open: fb_open,

release: fb_release

};

這是一個提供給應用程式的介面.

2)fbmem.c 實現瞭如下函式.

register_framebuffer(struct fb_info*fb_info);

unregister_framebuffer(struct fb_info*fb_info);

相關推薦

FrameBuffer 原理實現應用 (轉)

一、FrameBuffer 原理、實現與應用  一、FrameBuffer的原理    FrameBuffer 是出現在 2.2.xx 核心當中的一種驅動程式介面。    Linux是工作在保護模式下,所以使用者態程序是無法象DOS那樣使用顯示卡BIOS裡提供的中斷呼叫來實

FrameBuffer 原理實現應用

 一、FrameBuffer的原理    FrameBuffer 是出現在 2.2.xx 核心當中的一種驅動程式介面。    Linux是工作在保護模式下,所以使用者態程序是無法象DOS那樣使用顯示卡BIOS裡提供的中斷呼叫來實現直接寫屏,Linux抽象出

NIoBioaio原理及區別應用場景

在高效能的IO體系設計中,有幾個名詞概念常常會使我們感到迷惑不解。具體如下:  序號 問題 1 什麼是同步? 2 什麼是非同步? 3 什麼是阻塞? 4 什麼是非阻塞? 5 什麼是同步阻塞? 6 什麼是同步非阻

線段樹詳解 (原理實現應用

比如,以左側的的藍色為例,若該節點是其父節點的右子節點,就證明它右側的那個紫色節點不會留下,會被其父替代,所以沒必要在這一步計算,若該節點是其父節點的左子節點,就證明它右側的那個紫色節點會留在這一層,所以必須在此刻計算,否則以後都不會再計算這個節點了。這樣逐層上去,容易發現,對於左側的藍色節點來說,只要它是左

FrameBuffer 原理實現應用

個人Notes: What: A framebuffer device is an abstraction for the graphic hardware. It represents (名字源於)the frame buffer of some

NioBioAio 的原理及區別應用場景

目錄: 問題 在高效能的IO體系設計中,有幾個名詞概念常常會使我們感到迷惑不解。具體如下: 序號 問題 1 什麼是同步? 2 什麼是非同步? 3 什麼是阻塞? 4 什麼是非阻塞?

MDSHAMAC訊息摘要演算法實現應用

1.訊息摘要概述 訊息摘要(Message Digest)又稱為數字摘要(Digital Digest)。它是一個唯一對應一個訊息或文字的固定長度的值,它由一個單向Hash加密函式對訊息進行作用而產生。如果訊息在途中改變了,則接收者通過對收到訊息的新產生的摘要與原摘要比較,就可知道訊息是否被改變了。因此訊息摘

05: 分布式文件系統 FastDFS原理 FastDFS配置及應用

ble opp +++ load tin 分布式存儲 isa 4.2 libev 部署分布式存儲服務一、分布式文件系統介紹 二、配置分布式存儲服務2.1 配置主控節點(111) 裝包 修改配置文件 啟動服務 查看端口]# yum -y install

作業系統(4)虛擬儲存--覆蓋交換區域性性原理虛擬頁式儲存虛擬段式儲存缺頁異常

文章目錄 1. 虛擬儲存的需求背景 2. 覆蓋和交換技術 (過時技術) 3. 區域性性原理(虛擬儲存的可實現前提) 4. 虛擬儲存概念 4. 虛擬頁式儲存 5. 缺頁異常 1. 虛擬儲存的需

訓練集驗證集測試集的區別應用

0. 前言 最近一直在看論文、跑模型和做工程,很久沒有來發部落格了。但是在日常的學習和交流中,我感覺大家更加會關注當今最新的模型,最先進的演算法,但是對於一些非常基礎的內容的理解還不夠透徹,我也是想借此機會梳理清楚一些內容。 今天想講的是資料集的劃分,即訓練集,驗證集和測試集分別是啥

【Enweitech Software Works】創新實踐。致力於軟體網際網路研究…專注網站建設推廣軟體開發雲端計算手機APP定製電子資訊系統整合與應用、資訊保安資料管理軟體外包數字化解決方案和企業資訊化諮詢服務。

創新實踐。致力於軟體與網際網路研究…專注網站建設與推廣、軟體開發、雲端計算、手機APP定製、電子資訊系統整合與應用、資訊保安與資料管理、軟體外包、數字化解決方案和企業資訊化諮詢服務。...

Framebuffer原理使用測試

*二、FrameBuffer在Linux中的實現和機制* Framebuffer對應的原始檔在linux/drivers/video/目錄下。總的抽象裝置檔案為fbcon.c,在這個目錄下還有與各種顯示卡驅動相關的原始檔。  (一)、分析Framebuffer裝置驅動      需要特別提出的是在INT

Kafka簡介基本原理執行流程使用場景

一、簡介 Apache Kafka是分散式釋出-訂閱訊息系統,在 kafka官網上對 kafka 的定義:一個分散式釋出-訂閱訊息傳遞系統。 它最初由LinkedIn公司開發,Linkedin於2010年貢獻給了Apache基金會併成為頂級開源專案。Kafka

Javascript資料結構演算法--佇列(順序佇列優先佇列迴圈佇列)的實現用法

前言 佇列和棧非常類似,前面已經講過了棧的實現與用法,現在我們來說說佇列。 佇列介紹 佇列遵循FIFO(First In First Out,先進先出)原則的一組有序的項。 佇列是一種特殊的線性表,特殊之處在於它只允許在表的前端(front)進行刪除操作,而在表的後端(rear)進行插入操作,和棧一樣,佇列是

DESAESRSAMD5加密演算法辨析應用場景

資訊保安Cryptographic Techniques 對稱加密演算法 Data Encryption Standard(DES) DES 是一種典型的塊加密方法:將固定長度的明文通過一系列複雜的操作變成同樣長度的密文,塊的長度為64位。同時,DE

Servlet生命周期工作原理配置

move 重要 its 全局 對象 指定 code 化工 req Servlet生命周期 分為三個階段:   1,初始化階段 調用init()方法   2,響應客戶請求階段  調用service()方法   3,終止階段  調用destroy()方法 Servlet工作原

[Nginx]用Nginx實現應用結合的訪問控制 - 防盜鏈

計算公式 index user use 鏈接 vtk 兩個 link img 應用場景:圖片等資源須要設置權限,如:僅僅有認證過的用戶才幹訪問自己的圖片。 解決的方法:使用Nginx的防盜鏈模塊http_secure_link能夠實現,該模塊默認情況下不包括。故在

Nginx負載均衡ssl原理生成ssl密鑰對Nginx配置ssl

lnmp架構Nginx負載均衡當用戶訪問nginx定制好的域名時,nginx通過轉發到幾臺真實的站點,通過upstream實現[root@centos7 vhost]# vim /usr/local/nginx/conf/vhost/load.confupstream www.tt.com#自定義域名{#

kafka入門:簡介使用場景設計原理主要配置及集群搭建(轉)

request 上傳 結構 數據 send gist segments ring 希望 問題導讀: 1.zookeeper在kafka的作用是什麽? 2.kafka中幾乎不允許對消息進行“隨機讀寫”的原因是什麽? 3.kafka集群consumer和producer狀態信息

20162313 苑洪銘 實驗四 圖的實現應用

isempty 元素 list div 包含 之間 分代 自己 png 20162313 苑洪銘 實驗四 圖的實現與應用 實驗1 要求 用鄰接矩陣實現無向圖(邊和頂點都要保存),實現在包含添加和刪除結點的方法,添加和刪除邊的方法,size(),isEmpty(),廣度優先叠