?? frambuffer.txt
字號(hào):
在struct fb_info結(jié)構(gòu)中有變量:
struct fb_cmap cmap; /* Current cmap */
在fpgen基礎(chǔ)操作下提供:
extern int fbgen_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info);
extern int fbgen_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info);
在文件/* drivers/video/fbcmap.c */中提供更多的cmap應(yīng)用
extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);
extern void fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto);
extern int fb_get_cmap(struct fb_cmap *cmap, int kspc,
int (*getcolreg)(u_int, u_int *, u_int *, u_int *,u_int *, struct fb_info *),
struct fb_info *fb_info);
extern int fb_set_cmap(struct fb_cmap *cmap, int kspc,
int (*setcolreg)(u_int, u_int, u_int, u_int, u_int,struct fb_info *),
struct fb_info *fb_info);
extern struct fb_cmap *fb_default_cmap(int len);
extern void fb_invert_cmaps(void);
2. 通過文件解析
在anakinfb.c文件中,cmap如圖
在stifb.c
本文介紹的設(shè)備是位于/video目錄下面的anakinfb.c驅(qū)動(dòng)程序。雖然我不清楚那個(gè)設(shè)備的特性,但是從對(duì)程序的分析中我們?nèi)匀恢廊绾尉帉懸粋€(gè)frame buffer設(shè)備驅(qū)動(dòng)。
本文是個(gè)標(biāo)準(zhǔn)的fb驅(qū)動(dòng)。共221行,包含函數(shù)如下:
1. static int anakinfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, u_int *transp, struct fb_info *info) 31行
2. static int anakinfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,u_int transp, struct fb_info *info) 45行
3. static int anakinfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info) 57行
4. static int anakinfb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) 75行
5. static int anakinfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) 111行
6. static int anakinfb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) 117行
7. static int anakinfb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) 130行
8. static int anakinfb_switch_con(int con, struct fb_info *info) 147行
9. static int anakinfb_updatevar(int con, struct fb_info *info) 155行
10. static void anakinfb_blank(int blank, struct fb_info *info) 161行
11. int __init anakinfb_init(void) 178行
函數(shù)1,2是寄存器操作用。
函數(shù)3,4,5,6,7是fb_ops函數(shù)
函數(shù)8用于切換控制臺(tái)
函數(shù)9用于更新變量
函數(shù)10用于閃爍屏幕
函數(shù)11用于初始化設(shè)備
很奇怪,對(duì)fb設(shè)備的讀寫函數(shù)怎么沒有!值得說明的是open,release,read,write,ioctl,mmap等函數(shù)的實(shí)現(xiàn)是由fbmem.c文件實(shí)現(xiàn)了。也就是說所有的fb設(shè)備在給定了fb_info后,所有的操作都是一樣的。在明確的fb_info前提下,fbmem.c中的函數(shù)可以工作的很好。這樣大家應(yīng)該感到非常輕松了吧,只要完成上述的幾個(gè)設(shè)備相關(guān)的函數(shù),frame buffer設(shè)備的驅(qū)動(dòng)就寫完了:)
系統(tǒng)的結(jié)構(gòu)如圖:
Stifb驅(qū)動(dòng)模型
linux/drivers/video/stifb.c - Generic frame buffer driver for HP * workstations with STI (standard text interface) video firmware.
這個(gè)驅(qū)動(dòng)程序和前面的anakin設(shè)備完全不同,因?yàn)樗皇遣捎脴?biāo)準(zhǔn)的格式,而是根據(jù)based on skeletonfb, which wasCreated 28 Dec 1997 by Geert Uytterhoeven也就是skeletonfb.c提供的框架完成的。
共230行,包含函數(shù)如下:
1. static int sti_encode_fix(struct fb_fix_screeninfo *fix, const void *par, struct fb_info_gen *info) 60行
2. static int sti_decode_var(const struct fb_var_screeninfo *var,void *par, struct fb_info_gen *info) 71行
3. static int sti_encode_var(struct fb_var_screeninfo *var, const void *par, struct fb_info_gen *info) 78行
4. static void sti_get_par(void *par, struct fb_info_gen *info) 94行
5. static void sti_set_par(const void *par, struct fb_info_gen *info) 99行
6. static int sti_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue, unsigned *transp, struct fb_info *info) 104行
7. static int sti_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) 111行
8. static void sti_set_disp(const void *par, struct display *disp, struct fb_info_gen *info) 118行
9. static void sti_detect(void) 127行
10. static int sti_blank(int blank_mode, const struct fb_info *info) 132行
11. int __init stifb_init(void) 161行
12. void stifb_cleanup(struct fb_info *info) 201行
13. int __init stifb_setup(char *options) 208行
其中1到10是必須的,參考下面的圖。
11是初始化代碼
12.13沒有完成具體功能
再給出fb_fix_screeninfo系統(tǒng)調(diào)用結(jié)構(gòu)圖:
Frame buffer與console
Framebuffer作為顯卡在內(nèi)核中的注冊(cè)設(shè)備,為了滿足應(yīng)用需要,通常還要為console操作提供專用操作函數(shù)。
Console是系統(tǒng)提供的一種特殊的文本輸出終端,如圖所示。常用的console已經(jīng)不再是從前的單色顯示,而是16色或者更多顏色顯示。根據(jù)文本的代表的不同屬性,顯示不同的顏色。
把對(duì)console的支持內(nèi)嵌到fb的驅(qū)動(dòng)中,或許有其自己的道理,我沒有看出來。不過既然要提供這種支持,我們的驅(qū)動(dòng)程序就要添枝加葉了。
在準(zhǔn)fb設(shè)備設(shè)備驅(qū)動(dòng)中是沒有對(duì)console支持的。
只有在非標(biāo)準(zhǔn)的fb驅(qū)動(dòng),也就是基于skeletonfb.c架構(gòu)的程序,需要提供這部分代碼。
下面從各個(gè)方面介紹framebuffer對(duì)console的支持。
1. 各個(gè)文件中的支持
fb.h文件中
struct fb_info結(jié)構(gòu)中:
struct display *disp; /* initial display variable */
struct vc_data *display_fg; /* Console visible on this display */
int (*changevar)(int); /* tell console var has changed */
int (*switch_con)(int, struct fb_info*); /* tell fb to switch consoles */
fbgen.c文件中:
void fbgen_set_disp(int con, struct fb_info_gen *info)
int fbgen_update_var(int con, struct fb_info *info)
int fbgen_switch(int con, struct fb_info *info)
新增加文件fbcon.c
struct display fb_display[MAX_NR_CONSOLES];
char con2fb_map[MAX_NR_CONSOLES];
…..
新增加文件fbcon.h:
struct display_switch
struct display
新增文件console_struct.h:
struct vc_data
……
2. console中的顏色設(shè)定
該部分內(nèi)容準(zhǔn)備略掉,可以自行參考fbcon-cfb*.c文件。
3. console和fb的高層理解
當(dāng)我們?cè)趂b中引入console后,就相當(dāng)于把一張白紙變成了一個(gè)日記本。本來對(duì)于fb來說只有顏色和位置的關(guān)系,引入console后,首先就是console的描述。
每個(gè)console相當(dāng)于日記本的一頁,不同的console可以切換。Console因?yàn)槭且@示文本,又和字體聯(lián)系到一起。Console的管理是十分復(fù)雜的,遠(yuǎn)遠(yuǎn)超過了framebuffer本身。在RH9中,我們可以自己體驗(yàn)一下console和fb的協(xié)調(diào)問題。
使用Init3多用戶模式登陸,這里是沒有X server支持的。所有的輸入輸出都是基于console的。Framebuffer就相當(dāng)于你的顯示器。通過ALT+CTRL+F*,我們可以切換到不同的console,而每個(gè)console的設(shè)置都可以很獨(dú)立的完成。每隔console會(huì)在自己的數(shù)據(jù)區(qū)記錄歷史命令,在不同的console可以登陸不同的用戶到系統(tǒng)。但是,因?yàn)橹挥幸粋€(gè)屏幕,所以當(dāng)前可視的console只有一個(gè)。Frame buffer驅(qū)動(dòng)程序要能夠根據(jù)ALT+CTRL+F*切換命令去完成console的切換顯示。
這樣大家應(yīng)該明白frame buffer和console的關(guān)系了吧。后續(xù)我們會(huì)具體講述fb對(duì)console的支持。但是對(duì)console本身不會(huì)設(shè)計(jì)太多,具體參考tty或console的設(shè)計(jì)。當(dāng)完成了fb對(duì)console的支持,frame buffer device driver設(shè)計(jì)就完了:)
Fb console中的字體
/driver/video目錄下:
font_6x11.c,font_8x8.c,font_8x16.c
font_acorn_8x8.c,font_pearl_8x8.c,
font_sun8x16.c,font_sun12x22.c
fonts.c
這些文件都是用來處理在fbcon中的字體顯示問題。其中除最后一個(gè)文件fonts.c外,其他都是字模文件由cpi2fnt產(chǎn)生。
/include/video/目錄下:
font.h
1. 首先介紹font.h文件
font.h文件中,定義了字體的描述結(jié)構(gòu)
struct fbcon_font_desc {
int idx; //字體的索引號(hào)
char *name;//字體的描述
int width, height;//字模的寬和高
void *data;//字模的起始指針
int pref; //額外信息,平臺(tái)用
};
width的值不一定是8的整數(shù)倍,考慮到計(jì)算機(jī)存儲(chǔ)的問題,即使width小于8的整數(shù)倍,存儲(chǔ)時(shí)仍以字節(jié)為單位,不足的右補(bǔ)齊0。
Linux內(nèi)核自帶了7種字體,name依次為:
font_vga_8x8,
font_vga_8x16,
font_pearl_8x8,
font_vga_6x11,
font_sun_8x16,
font_sun_12x22,
font_acorn_8x8;
根據(jù)定義name長度不大于32字節(jié)。
2. Font.c文件
/* 根據(jù)字體名返回該字體的描述結(jié)構(gòu) */
struct fbcon_font_desc *fbcon_find_font(char *name);
/*根據(jù)屏幕大小,獲取默認(rèn)字體描述 */
struct fbcon_font_desc *fbcon_get_default_font(int xres, int yres);
由此看來,linux中基于fbcon的字體比較單一,描述和使用也相對(duì)簡單。主要是由于采用字模描述,只描述256個(gè)ascii字符,故存儲(chǔ)空間不大,從2048到11264不等。
Fbcon中的顏色查找表
Fbcon-cfbx表示該console使用的是xbpp顏色描述。顏色數(shù)為2^x。
在此,我們僅以x=8,x=24舉例,使用顏色分別是256色和真彩16M。
/driver/video/fbcon-cfb8.c
/driver/video/fbcon-cfb24.c
/include/video/fbcon-cfb8.h
/include/video/fbcon-cfb24.h
這4個(gè)文件實(shí)現(xiàn)的具體的操作,而fbcon的底層操作,參考前面的fbcon的介紹,不重復(fù)了:)
實(shí)現(xiàn)fbcon的顏色映射只需完成下面的功能,以fb8為例:
struct display_switch fbcon_cfb8;
void fbcon_cfb8_setup(struct display *p);
void fbcon_cfb8_bmove(struct display *p, int sy, int sx, int dy, int dx, int height, int width);
void fbcon_cfb8_clear(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width);
void fbcon_cfb8_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx);
void fbcon_cfb8_putcs(struct vc_data *conp, struct display *p, const unsigned short *s, int count, int yy, int xx);
void fbcon_cfb8_revc(struct display *p, int xx, int yy);
void fbcon_cfb8_clear_margins(struct vc_data *conp, struct display *p,int bottom_only);
fbcon_cfb8是系統(tǒng)的實(shí)現(xiàn)關(guān)鍵,具體解釋參考fbcon介紹。
fbcon_cfb8_setup函數(shù)完成設(shè)定display結(jié)構(gòu)中next_line和next_palne的值。
fbcon_cfb8_bmove函數(shù)完成當(dāng)前坐標(biāo)的移動(dòng)。
fbcon_cfb8_clear函數(shù)通過調(diào)用rectfill函數(shù)清屏幕緩沖區(qū)。
fbcon_cfb8_putc函數(shù)向屏幕輸出單字符,字體寬度必須小于等于16。
fbcon_cfb8_putcs函數(shù)向屏幕輸出字符串。
fbcon_cfb8_revc函數(shù)從屏幕輸入單個(gè)字符,并回顯到fb上。
fbcon_cfb8_clear_margins函數(shù)和fbcon_cfb8_clear類似,調(diào)用rectfill清除區(qū)域。
其中,fb_writel函數(shù)和fb_readl函數(shù)實(shí)現(xiàn)輸入輸出的底層操作。這兩個(gè)函數(shù)實(shí)際上實(shí)在fbcon_h中定義的宏操作,IOMEM操作而已。
關(guān)注一下“(nibbletab_cfb8[*cdat++ >> 4] & eorx) ^ bgx,”
這是所謂8bpp的具體實(shí)現(xiàn),不同的位深就在寫fb緩沖時(shí)體現(xiàn)了。讓我們從后向前分析,
1.()^bgx,顏色和背景色異或,只有這樣才能保證背景色改變時(shí),文字一直顯示。
2.~&eorx,eorx是前景色和背景色異或后的值,只有在前景色和背景色一致的時(shí)候,eorx才是0。
3. nibbletab_cfb8[~],根據(jù)字體的~值,調(diào)用查找表,取顏色值
4.~從字體文件中去讀字模的值。
還有點(diǎn)疑問,就是這兩句的作用,attr_fgcol在fbcon_h中定義:
fgx=attr_fgcol(p,c);
bgx=attr_bgcol(p,c);
從前面的看,c應(yīng)該是個(gè)字符的ascii碼,ascii與顏色有什么關(guān)系呢?研究中….
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -