分类: LINUX
2008-04-11 19:07:11
本文介绍的设备是位于/video目录下面的anakinfb.c驱动程序。虽然我不清楚那个设备的特性,但是从对程序的分析中我们仍然知道如何编写一个frame buffer设备驱动。
本文是个标准的fb驱动。共221行,包含函数如下:
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行
函数1,2是寄存器操作用。
函数3,4,5,6,7是fb_ops函数
函数8用于切换控制台
函数9用于更新变量
函数10用于闪烁屏幕
函数11用于初始化设备
很奇怪,对fb设备的读写函数怎么没有!值得说明的是open,release,read,write,ioctl,mmap等函数的实现是由fbmem.c文件实现了。也就是说所有的fb设备在给定了fb_info后,所有的操作都是一样的。在明确的fb_info前提下,fbmem.c中的函数可以工作的很好。这样大家应该感到非常轻松了吧,只要完成上述的几个设备相关的函数,frame buffer设备的驱动就写完了:)
系统的结构如图:
Stifb驱动模型
linux/drivers/video/stifb.c - Generic frame buffer driver for HP * workstations with STI (standard text interface) video firmware.
这个驱动程序和前面的anakin设备完全不同,因为他不是采用标准的格式,而是根据based on skeletonfb, which wasCreated 28 Dec 1997 by Geert Uytterhoeven也就是skeletonfb.c提供的框架完成的。
共230行,包含函数如下:
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系统调用结构图:
Frame buffer与console
Framebuffer作为显卡在内核中的注册设备,为了满足应用需要,通常还要为console操作提供专用操作函数。
Console是系统提供的一种特殊的文本输出终端,如图所示。常用的console已经不再是从前的单色显示,而是16色或者更多颜色显示。根据文本的代表的不同属性,显示不同的颜色。
把对console的支持内嵌到fb的驱动中,或许有其自己的道理,我没有看出来。不过既然要提供这种支持,我们的驱动程序就要添枝加叶了。
在准fb设备设备驱动中是没有对console支持的。
只有在非标准的fb驱动,也就是基于skeletonfb.c架构的程序,需要提供这部分代码。
下面从各个方面介绍framebuffer对console的支持。
1. 各个文件中的支持
fb.h文件中
struct fb_info结构中:
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中的颜色设定
该部分内容准备略掉,可以自行参考fbcon-cfb*.c文件。
3. console和fb的高层理解
当我们在fb中引入console后,就相当于把一张白纸变成了一个日记本。本来对于fb来说只有颜色和位置的关系,引入console后,首先就是console的描述。
每个console相当于日记本的一页,不同的console可以切换。Console因为是要显示文本,又和字体联系到一起。Console的管理是十分复杂的,远远超过了framebuffer本身。在RH9中,我们可以自己体验一下console和fb的协调问题。
使用Init3多用户模式登陆,这里是没有X server支持的。所有的输入输出都是基于console的。Framebuffer就相当于你的显示器。通过ALT+CTRL+F*,我们可以切换到不同的console,而每个console的设置都可以很独立的完成。每隔console会在自己的数据区记录历史命令,在不同的console可以登陆不同的用户到系统。但是,因为只有一个屏幕,所以当前可视的console只有一个。Frame buffer驱动程序要能够根据ALT+CTRL+F*切换命令去完成console的切换显示。
这样大家应该明白frame buffer和console的关系了吧。后续我们会具体讲述fb对console的支持。但是对console本身不会设计太多,具体参考tty或console的设计。当完成了fb对console的支持,frame buffer device driver设计就完了:)