1、framebuffer 幀緩沖
幀緩沖(framebuffer)是Linux 系統為顯示設備提供的一個接口,它將顯示緩沖區抽象,屏蔽圖像硬件的底層差異,允許上層應用程序在圖形模式下直接對顯示緩沖區進行讀寫操作。用戶不必關心物理顯示緩沖區的具體位置及存放方式,這些都由幀緩沖設備驅動本身來完成。
framebuffer機制模仿顯卡的功能,將顯卡硬件結構抽象為一系列的數據結構,可以通過framebuffer的讀寫直接對顯存進行操作。用戶可以將framebuffer看成是顯存的一個映像,將其映射到進程空間後,就可以直接進行讀寫操作,寫操作會直接反映在屏幕上。
framebuffer是個字符設備,主設備號為29,對應於/dev/fb%d 設備文件。
通常,使用如下方式(前面的數字表示次設備號)
0 = /dev/fb0 第一個fb 設備
1 = /dev/fb1 第二個fb 設備
fb 也是一種普通的內存設備,可以讀寫其內容。例如,屏幕抓屏:cp /dev/fb0 myfilefb 雖然可以像內存設備(/dev/mem)一樣,對其read,write,seek 以及mmap。但區別在於fb 使用的不是整個內存區,而是顯存部分。
2、fb與應用程序的交互
對於用戶程序而言,它和其他的設備並沒有什麼區別,用戶可以把fb看成是一塊內存,既可以向內存中寫數據,也可以讀數據。fb的顯示緩沖區位於內核空間,應用程序可以把此空間映射到自己的用戶空間,在進行操作。
在應用程序中,操作/dev/fbn的一般步驟如下:
(1)打開/dev/fbn設備文件。
(2)用ioctl()操作取得當前顯示屏幕的參數,如屏幕分辨率、每
個像素點的比特數。根據屏幕參數可計算屏幕緩沖區的大小。
(3)用mmap()函數,將屏幕緩沖區映射到用戶空間。
(4)映射後就可以直接讀/寫屏幕緩沖區,進行繪圖和圖片顯示了。
3、fb的結構及其相關結構體
在linux中,fb設備驅動的源碼主要在Fb.h (linux2.6.28\include\linux)和Fbmem.c (linux2.6.28\drivers\video)兩個文件中,它們是fb設備驅動的中間層,為上層提供系統調用,為底層驅動提供接口。
在fb.h文件中有fb驅動需要使用的很多結構,我們先對這些結構體進行說明:
(1)、
一個幀緩沖區對應一個struct fb_info結構,它包括了幀緩沖設備的屬性和操作的完整集合,每個幀設備都有一個fb_info結構體。源碼如下:
struct fb_info {
int node;
int flags;
struct mutex lock;/* Lock for open/release/ioctl funcs */互斥鎖
struct fb_var_screeninfo var;/* Current var */當前緩沖區的可變參數
struct fb_fix_screeninfo fix;/* Current fix */固定參數
struct fb_monspecs monspecs;/* Current Monitor specs */當前顯示器標志
struct work_struct queue;/* Framebuffer event queue */幀緩沖事件隊列
struct fb_pixmap pixmap;/* Image hardware mapper */圖像硬件mapper
struct fb_pixmap sprite;/* Cursor hardware mapper */光標硬件mapper
struct fb_cmap cmap;/* Current cmap */當前的調色板
struct list_head modelist; /* mode list */
struct fb_videomode *mode;/* current mode */當前的視頻模式
#ifdef CONFIG_FB_BACKLIGHT如果配置了LCD支持背光燈
/* assigned backlight device */
/* set before framebuffer registration,
remove after unregister */背光調整
struct backlight_device *bl_dev;
/* Backlight level curve */
struct mutex bl_curve_mutex;
u8 bl_curve[FB_BACKLIGHT_LEVELS];
#endif
#ifdef CONFIG_FB_DEFERRED_IO
struct delayed_work deferred_work;
struct fb_deferred_io *fbdefio;
#endif
struct fb_ops *fbops;幀緩沖操作函數集
struct device *device;/* This is the parent */父設備
struct device *dev;/* This is this fb device */fb設備
int class_flag; /* private sysfs flags */私有的sysfs標志
#ifdef CONFIG_FB_TILEBLITTING
struct fb_tile_ops *tileops; /* Tile Blitting */圖塊blitting
#endif
char __iomem *screen_base;/* Virtual address */虛擬基地址
unsigned long screen_size;/* Amount of ioremapped VRAM or 0 */ ioremap的虛擬內存大小
void *pseudo_palette;/* Fake palette of 16 colors */ 偽16位調色板
#define FBINFO_STATE_RUNNING 0
#define FBINFO_STATE_SUSPENDED 1
u32 state; /* Hardware state i.e suspend */硬件的狀態
void *fbcon_par; /* fbcon use-only private area */
/* From here on everything is device dependent */
void *par;
};
(2)、
/*
* Frame buffer operations
*
* LOCKING NOTE: those functions must _ALL_ be called with the console
* semaphore held, this is the only suitable locking mechanism we have
* in 2.6. Some may be called at interrupt time at this point though.
*/
fb_ops結構體用來實現對幀緩沖設備的操作,這些函數需要驅動開發人員編寫,
struct fb_ops {
/* open/release and usage marking */
struct module *owner;
打開和釋放
int (*fb_open)(struct fb_info *info, int user);
int (*fb_release)(struct fb_info *info, int user);
這兩個函數對於非線性布局的/常規內存映射無法工作的幀緩沖設備需要
/* For framebuffers with strange non linear layouts or that do not
* work with normal memory mapped access
*/
ssize_t (*fb_read)(struct fb_info *info, char __user *buf,
size_t count, loff_t *ppos);
ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos);
檢測可變參數,並調整到支持的值
/* checks var and eventually tweaks it to something supported,
* DO NOT MODIFY PAR */
int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);
設置視頻模式
/* set the video mode according to info->var */
int (*fb_set_par)(struct fb_info *info);
設置color寄存器的值
/* set color register */
int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp, struct fb_info *info);
批量設置color寄存器,設置顏色表
/* set color registers in batch */
int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);
顯示空白
/* blank display */
int (*fb_blank)(int blank, struct fb_info *info);
pan顯示
/* pan display */
int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);
填充矩形
/* Draws a rectangle */
void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
數據復制
/* Copy data from area to another */
void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
圖形填充
/* Draws a image to the display */
void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);
繪制光標
/* Draws cursor */
int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);
旋轉顯示
/* Rotates the display */
void (*fb_rotate)(struct fb_info *info, int angle);
等待blit空閒
/* wait for blit idle, optional */
int (*fb_sync)(struct fb_info *info);
fb特定的ioctl操作
/* perform fb specific ioctl (optional) */
int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
unsigned long arg);
處理32兼容的ioctl操作
/* Handle 32bit compat ioctl (optional) */
int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
unsigned long arg);
fb特定的mmap操作
/* perform fb specific mmap */
int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
保存目前的硬件狀態
/* save current hardware state */
void (*fb_save_state)(struct fb_info *info);
恢復被保存的硬件狀態
/* restore saved state */
void (*fb_restore_state)(struct fb_info *info);
通過fb_info獲得framebuffer的能力
/* get capability given var */
void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
struct fb_var_screeninfo *var);
};
(3)、
fb_fix_screeninfo結構體中,記錄了用戶不能修改的固定顯示控制器參數。這些固定的參數如緩沖區的物理地址、緩沖區的長度等等。
struct fb_fix_screeninfo {
char id[16]; /* identification string eg "TT Builtin" */
字符串形式的標識符
unsigned long smem_start;/* Start of frame buffer mem */
/* (physical address) */
fb緩存的開始位置
__u32 smem_len;/* Length of frame buffer mem */
fb緩存的長度
__u32 type; /* see FB_TYPE_* */
FB_TYPE_*類型
__u32 type_aux;/* Interleave for interleaved Planes */
分界
__u32 visual; /* see FB_VISUAL_* */
屏幕使用的色彩模式
__u16 xpanstep;/* zero if no hardware panning */
如果沒有硬件panning ,賦0
__u16 ypanstep;/* zero if no hardware panning */
__u16 ywrapstep;/* zero if no hardware ywrap */
1行的字節數
__u32 line_length;/* length of a line in bytes */
內存映射I/O的開始位置
unsigned long mmio_start;/* Start of Memory Mapped I/O */
/* (physical address) */
內存映射I/O的長度
__u32 mmio_len;/* Length of Memory Mapped I/O */
__u32 accel; /* Indicate to driver which */
/* specific chip/card we have*/
__u16 reserved[3];/* Reserved for future compatibility */
};
(4)、
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 to visible */
__u32 yoffset;/* resolution */
虛擬到可見之間的偏移
__u32 bits_per_pixel;/* guess what */
每像素位數,BPP
__u32 grayscale;/* != 0 Graylevels instead of colors */
非0時指灰度
struct fb_bitfield red;/* bitfield in fb mem if true color, */
struct fb_bitfield green;/* else only length is significant */
struct fb_bitfield blue;
fb緩存的R\G\B位域
struct fb_bitfield transp;/* transparency */
透明度
__u32 nonstd; /* != 0 Non standard pixel format */
!= 0 非標准像素格式
__u32 activate;/* see FB_ACTIVATE_* */
__u32 height; /* height of picture in mm */
屏幕的高度
__u32 width; /* width of picture in mm */
屏幕的寬度
__u32 accel_flags;/* (OBSOLETE) see fb_info.flags */
fb_info的標志
/* Timing: All values in pixclocks, except pixclock (of course) */
__u32 pixclock;/* pixel clock in ps (pico seconds) */
/* 像素時鐘(皮秒) */
__u32 left_margin;/* time from sync to picture */
行切換:從同步到繪圖之間的延遲
__u32 right_margin;/* time from picture to sync */
行切換:從繪圖到同步之間的延遲
__u32 upper_margin;/* time from sync to picture */
幀切換:從同步到繪圖之間的延遲
__u32 lower_margin;
幀切換:從繪圖到同步之間的延遲
__u32 hsync_len;/* length of horizontal sync */
水平同步的長度
__u32 vsync_len;/* length of vertical sync */
垂直同步的長度
__u32 sync; /* see FB_SYNC_* */
__u32 vmode; /* see FB_VMODE_* */
__u32 rotate; /* angle we rotate counter clockwise */
順時鐘旋轉的角度
__u32 reserved[5];/* Reserved for future compatibility */
};
(5)、
fb_cmap結構體中記錄了顏色板信息,即調色板信息。,用戶空間可以通過ioctl()的FBIOGETCMAP和 FBIOPUTCMAP命令讀取或設定顏色表。
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 */透明度
};
上面這些結構體之間有什麼關系呢?看下圖:
(6)、
fb_bitfield 結構體描述每一像素顯示緩沖區的組織方式,包含位域偏移、位域長度和MSB 指示,
struct fb_bitfield {
__u32 offset; /* beginning of bitfield */
位域偏移
__u32 length; /* length of bitfield */
位域長度
__u32 msb_right;/* != 0 : Most significant bit is */
/* right */
MSB
};