Framebuffer對(duì)應(yīng)的源文件在linux/drivers/video/目錄下。總的抽象設(shè)備文件為fbcon.c,在這個(gè)目錄下還有與各種顯卡驅(qū)動(dòng)相關(guān)的源文件。 //這個(gè)文件要好好看看
(一)、分析Framebuffer設(shè)備驅(qū)動(dòng)
需要特別提出的是在INTEL平臺(tái)上,老式的VESA 1.2 卡,如CGA/EGA卡,是不能支持Framebuffer的,因?yàn)镕ramebuffer要求顯卡支持線性幀緩沖,即CPU可以訪問(wèn)顯緩沖中的每一位,但是VESA 1.2 卡只能允許CPU一次訪問(wèn)64K的地址空間。 FrameBuffer設(shè)備驅(qū)動(dòng)基于如下兩個(gè)文件: 1) linux/include/linux/fb.h 2) linux/drivers/video/fbmem.c 下面分析這兩個(gè)文件。
1、fb.h 幾乎主要的結(jié)構(gòu)都是在這個(gè)中文件定義的。這些結(jié)構(gòu)包括: 1)fb_var_screeninfo 這個(gè)結(jié)構(gòu)描述了顯示卡的特性: NOTE:::: __u32 是表示 unsigned 不帶符號(hào)的 32 bits 的數(shù)據(jù)類型,其余類推。這是 Linux 內(nèi)核中所用到的數(shù)據(jù)類型,如果是開(kāi)發(fā)用戶空間(user-space)的程序,可以根據(jù)具體計(jì)算機(jī)平臺(tái)的情況,用 unsigned long 等等來(lái)代替 struct fb_var_screeninfo { __u32 xres; /* visible resolution */ //可視區(qū)域 __u32 yres; __u32 xres_virtual; /* virtual resolution */ //可視區(qū)域 __u32 yres_virtual; __u32 xoffset; /* offset from virtual to visible resolution */ //可視區(qū)域的偏移 __u32 yoffset; __u32 bits_per_pixel; /* guess what */ //每一象素的bit數(shù)
__u32 grayscale; /* != 0 Gray levels instead of colors *///等于零就成黑白 struct fb_bitfield red; /* bitfield in fb mem if true color, */真彩的bit機(jī)構(gòu)
struct fb_bitfield green; /* else only length is significant */ struct fb_bitfield blue; struct fb_bitfield transp; /* transparency */ 透明 __u32 nonstd; /* != 0 Non standard pixel format */ 不是標(biāo)準(zhǔn)格式
__u32 activate; /* see FB_ACTIVATE_* */
__u32 height; /* height of picture in mm */ 內(nèi)存中的圖像高度
__u32 width; /* width of picture in mm */ 內(nèi)存中的圖像寬度 __u32 accel_flags; /* acceleration flags (hints) */ 加速標(biāo)志
/* Timing: All values in pixclocks, except pixclock (of course) */
時(shí)序-_-這些部分就是顯示器的顯示方法了,可以找相關(guān)的資料看看
__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 */ 水平可視區(qū)域 __u32 vsync_len; /* length of vertical sync */ 垂直可視區(qū)域 __u32 sync; /* see FB_SYNC_* */ __u32 vmode; /* see FB_VMODE_* */ __u32 reserved[6]; /* Reserved for future compatibility */ 備用-以后開(kāi)發(fā) }; 2) fb_fix_screeninfon
這個(gè)結(jié)構(gòu)在顯卡被設(shè)定模式后創(chuàng)建,它描述顯示卡的屬性,并且系統(tǒng)運(yùn)行時(shí)不能被修改;比如FrameBuffer內(nèi)存的起始地址。它依賴于被設(shè)定的模式,當(dāng)一個(gè)模式被設(shè)定后,內(nèi)存信息由顯示卡硬件給出,內(nèi)存的位置等信息就不可以修改。 struct fb_fix_screeninfo {
char id[16]; /* identification string eg "TT Builtin" */ID unsigned long smem_start; /* Start of frame buffer mem */ 內(nèi)存起始 /* (physical address) */ 物理地址 __u32 smem_len; /* Length of frame buffer mem */ 內(nèi)存大小 __u32 type; /* see FB_TYPE_* */ __u32 type_aux; /* Interleave for interleaved Planes */插入?yún)^(qū)域? __u32 visual; /* see FB_VISUAL_* */ __u16 xpanstep; /* zero if no hardware panning */沒(méi)有硬件設(shè)備就為零 __u16 ypanstep; /* zero if no hardware panning */ __u16 ywrapstep; /* zero if no hardware ywrap */ __u32 line_length; /* length of a line in bytes */ 一行的字節(jié)表示 unsigned long mmio_start; /* Start of Memory Mapped I/O */內(nèi)存映射的I/O起始 /* (physical address) */ __u32 mmio_len; /* Length of Memory Mapped I/O */ I/O的大小 __u32 accel; /* Type of acceleration available */ 可用的加速類型 __u16 reserved[3]; /* Reserved for future compatibility */ }; 3) fb_cmap
描述設(shè)備無(wú)關(guān)的顏色映射信息??梢酝ㄟ^(guò)FBIOGETCMAP 和 FBIOPUTCMAP 對(duì)應(yīng)的ioctl操作設(shè)定或獲取顏色映射信息. struct fb_cmap {
__u32 start; /* First entry */ 第一個(gè)入口 __u32 len; /* Number of entries */ 入口的數(shù)字 __u16 *red; /* Red values */ 紅 __u16 *green; __u16 *blue; __u16 *transp; /* transparency, can be NULL */ 透明,可以為零 }; 4) fb_info
定義當(dāng)顯卡的當(dāng)前狀態(tài);fb_info結(jié)構(gòu)僅在內(nèi)核中可見(jiàn),在這個(gè)結(jié)構(gòu)中有一個(gè)fb_ops指針, 指向驅(qū)動(dòng)設(shè)備工作所需的函數(shù)集。 struct fb_info {
char modename[40]; /* default video mode */ 默認(rèn)的視頻卡類型 kdev_t node; int flags; int open; /* Has this been open already ? */ 被打開(kāi)過(guò)么? #define FBINFO_FLAG_MODULE 1 /* Low-level driver is a module */ struct fb_var_screeninfo var; /* Current var */ 現(xiàn)在的視頻信息 struct fb_fix_screeninfo fix; /* Current fix */ 修正的信息 struct fb_monspecs monspecs; /* Current Monitor specs */ 現(xiàn)在的顯示器模式 struct fb_cmap cmap; /* Current cmap */ 當(dāng)前優(yōu)先級(jí) struct fb_ops *fbops; char *screen_base; /* Virtual address */ 物理基址 struct display *disp; /* initial display variable */初始化 struct vc_data *display_fg; /* Console visible on this display */ char fontname[40]; /* default font name */默認(rèn)的字體 devfs_handle_t devfs_handle; /* Devfs handle for new name */ devfs_handle_t devfs_lhandle; /* Devfs handle for compat. symlink */兼容 int (*changevar)(int); /* tell console var has changed */ 告訴console變量修改了 int (*switch_con)(int, struct fb_info*); /* tell fb to switch consoles */ 告訴fb選擇consoles int (*updatevar)(int, struct fb_info*); /* tell fb to update the vars */ 告訴fb更新變量 void (*blank)(int, struct fb_info*); /* tell fb to (un)blank the screen */告訴fb使用黑白模式(或者不黑) /* arg = 0: unblank */arg=0的時(shí)候黑白模式 /* arg > 0: VESA level (arg-1) */ arg>0時(shí)候選擇VESA模式 void *pseudo_palette; /* Fake palette of 16 colors and the cursor's color for non palette mode */ 修正調(diào)色板 /* From here on everything is device dependent */ 現(xiàn)在就可以使用了 void *par; }; 5) struct fb_ops
用戶應(yīng)用可以使用ioctl()系統(tǒng)調(diào)用來(lái)操作設(shè)備,這個(gè)結(jié)構(gòu)就是用一支持ioctl()的這些操作的。 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); /* 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)(struct fb_var_screeninfo *var, int con, struct fb_info *info); /* perform fb specific ioctl (optional) */ int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg, int con, struct fb_info *info); /* perform fb specific mmap */ int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma); /* switch to/from raster image mode */ int (*fb_rasterimg)(struct fb_info *info, int start); }; 6) structure map
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 2、 fbmem.c fbmem.c 處于Framebuffer設(shè)備驅(qū)動(dòng)技術(shù)的中心位置.它為上層應(yīng)用程序提供系統(tǒng)調(diào)用也為下一層的特定硬件驅(qū)動(dòng)提供接口;那些底層硬件驅(qū)動(dòng)需要用到這兒的接口來(lái)向系統(tǒng)內(nèi)核注冊(cè)它們自己. fbmem.c 為所有支持FrameBuffer的設(shè)備驅(qū)動(dòng)提供了通用的接口,避免重復(fù)工作. 1) 全局變量
struct fb_info *registered_fb[FB_MAX];
int num_registered_fb; 這兩變量記錄了所有fb_info 結(jié)構(gòu)的實(shí)例,fb_info 結(jié)構(gòu)描述顯卡的當(dāng)前狀態(tài),所有設(shè)備對(duì)應(yīng)的fb_info 結(jié)構(gòu)都保存在這個(gè)數(shù)組中,當(dāng)一個(gè)FrameBuffer設(shè)備驅(qū)動(dòng)向系統(tǒng)注冊(cè)自己時(shí),其對(duì)應(yīng)的fb_info 結(jié)構(gòu)就會(huì)添加到這個(gè)結(jié)構(gòu)中,同時(shí)num_registered_fb 為自動(dòng)加1. static struct {
const char *name; int (*init)(void); int (*setup)(void); } fb_drivers[] __initdata= { ....}; 如果FrameBuffer設(shè)備被靜態(tài)鏈接到內(nèi)核,其對(duì)應(yīng)的入口就會(huì)添加到這個(gè)表中;如果是動(dòng)態(tài)加載的,即使用insmod/rmmod,就不需要關(guān)心這個(gè)表。
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 }; 這是一個(gè)提供給應(yīng)用程序的接口. 2)fbmem.c 實(shí)現(xiàn)了如下函數(shù).
register_framebuffer(struct fb_info *fb_info);
unregister_framebuffer(struct fb_info *fb_info); 這兩個(gè)是提供給下層FrameBuffer設(shè)備驅(qū)動(dòng)的接口,設(shè)備驅(qū)動(dòng)通過(guò)這兩函數(shù)向系統(tǒng)注冊(cè)或注銷自己。幾乎底層設(shè)備驅(qū)動(dòng)所要做的所有事情就是填充fb_info結(jié)構(gòu)然后向系統(tǒng)注冊(cè)或注銷它。
|
|
來(lái)自: 00lacey00 > 《Frame Buffer》