之前看过很多书籍和网上资料,了解了linux中Framebuffer的框架和一些结构体以及必备的硬件知识。但令本人深感"痛恨"的是,这些资料无不是点到为止(有些深入一些有些只介绍大概),贴代码的时候总是省略了很多内容,难道就不能有一本书或一篇文章将整个Framebuffer代码全部讲完吗?在这里我想"挑战"一下。
本篇文章基于内核版本linux3.0.x,虽然已经不是很新,但驱动中的机制是万变不离其宗的,因此版本显得不是那么重要了。
Linux中Framebuffer驱动动能主要涉及以下两个文件:
1. kernel源代码/include/linux/fb.h: Framebuffer驱动的头文件;
2. kernel源代码/drivers/video/fbmem.c: Framebuffer驱动的核心实现文件。
刚上手的人都迫不及待地想直接看源代码,我当初上手时这种愿望尤其强烈,因此在这里先跳过头文件,直接看源文件中的代码。
先看入口函数,在fbmem.c中:
/**
* fbmem_init - init frame buffer subsystem
*
* Initialize the frame buffer subsystem.
*
* NOTE: This function is _only_ to be called by drivers/char/mem.c.
*
*/
static int __init
fbmem_init(void)
{
proc_create("fb", 0, NULL, &fb_proc_fops);
if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
printk("unable to get major %d for fb devs\n", FB_MAJOR);
fb_class = class_create(THIS_MODULE, "graphics");
if (IS_ERR(fb_class)) {
printk(KERN_WARNING "Unable to create fb class; errno = %ld\n", PTR_ERR(fb_class));
fb_class = NULL;
}
return 0;
}
#ifdef MODULE
module_init(fbmem_init);
static void __exit
fbmem_exit(void)
{
remove_proc_entry("fb", NULL);
class_destroy(fb_class);
unregister_chrdev(FB_MAJOR, "fb");
}
module_exit(fbmem_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Framebuffer base");
#else
subsys_initcall(fbmem_init);
#endif
这段代码即是framebuffer的入口点,一切从这里开始.
#ifdef自不必多说,学过C语言的都知道这是预编译指令,这里不想多说,看到内核驱动级代码的人不会连这个都不知道.这段代码的意思是如果framebuffer驱动作为模块加载,则执行以下这段:
static int __init
fbmem_init(void)
{
proc_create("fb", 0, NULL, &fb_proc_fops);
if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
printk("unable to get major %d for fb devs\n", FB_MAJOR);
fb_class = class_create(THIS_MODULE, "graphics");
if (IS_ERR(fb_class)) {
printk(KERN_WARNING "Unable to create fb class; errno = %ld\n", PTR_ERR(fb_class));
fb_class = NULL;
}
return 0;
}
module_init(fbmem_init);
static void __exit
fbmem_exit(void)
{
remove_proc_entry("fb", NULL);
class_destroy(fb_class);
unregister_chrdev(FB_MAJOR, "fb");
}
module_exit(fbmem_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Framebuffer base");
如果不是作为模块加载,而是直接编译进内核,则执行以下这句:
subsys_initcall(fbmem_init);
其中:
kernel源代码/include/linux/init.h中:
#define module_init(x) __initcall(x);
#define __initcall(fn) device_initcall(fn)
#define device_initcall(fn) __define_initcall("6",fn,6)
#define subsys_initcall(fn)__define_initcall("4",fn,4)
具体意义这里不作过多解释,后续我会专门发文章介绍。只要记住一个是模块初始化,一个是子系统初始化。
module_init()或subsys_initcall()中调用了fbmem_init(),module_exit()中调用了fbmem_exit(),此外还有一些结构体和一些调用函数。这些都是什么意思?
要弄清楚这些内容,且听下回分解。