Linux中Framebuffer驱动详解1

来源:互联网 发布:水利数据采集监测系统 编辑:程序博客网 时间:2024/05/24 03:45

之前看过很多书籍和网上资料,了解了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(),此外还有一些结构体和一些调用函数。这些都是什么意思?

要弄清楚这些内容,且听下回分解。

 

0 0
原创粉丝点击