Linux | Framebuffer内核源码阅读

一、framebuffer简介

       Framebuffer是操作系统供用户直接控制屏幕的接口,也就是直接对显存进行操作的接口。用户可以将Framebuffer看成是显示内存的一个映像,将其映射到进程地址空间之后,就可以直接进行读写操作,而写操作可以立即反应在屏幕上。这种操作是抽象的,统一的,用户不必关心物理显存的位置、换页机制等等具体细节,这些都是由 Framebufer设备驱动来完成。

二、framebuffer子系统研究

2.1 研究材料

研究的源码为kernel-3.4.39,研究的文件为fb.h,该文件在/include/linux下。

2.2 关键结构体

Framebuffer子系统的核心结构体是fb_info,其包含了各种显示控制器的可变及不可变信息、framebuffer的操作框架等。里面包装了各种描述framebuffer的成员以及操作控制framebuffer的方法。下面的其他结构体都是被包含在fb_info里面的,fb.h文件里面的结构体绝大部分也是被包含在fb_info里面。

描述显示控制器的一些可变参数,用户可以进行修改。

描述显示控制器的固定变量,用户不能进行修改。

fb_ops结构体类似于file_operation结构体,里面主要是一些函数指针,指向一些进行相关文件操作就会触发的函数。

描述监视器的详细规格信息的结构体。

用于帧缓冲设备的像素图或光标图像的内存缓冲区信息的结构体,fb_info中有pixmap和sprite两个成员,分别描述图片的硬件映射器和游标的硬件映射器。

表示当前的颜色映射表的结构体,每个映射表的条目为一个数组。

       描述一种特定的视频模式的结构体。

2.3 总结

       如图,fb.h中的主要结构体是fb_info,该结构体里面包含了fb.h里面的大部分结构体,因此也是描述framebuffer的主要结构体。当需要修改framebuffer的参数时,操作var成员;当需要使用framebuffer的一些固定信息,如framebuffer的基地址等,操作fix成员;当对framebuffer进行打开、读和写等操作时,使用fbops成员。fb_info包含了framebuffer的各种信息和操作框架,就像一个书架,书架上面的图书就是fb_info上面的成员,当用户需要控制framebuffer实现某些功能时,根据需求使用书架上面的书,也就是fb_info里面的成员。

三、framebuffe驱动研究

3.1 研究材料

       kernel-3.4.39中的/drivers目录下存放着各种Linux自带的驱动,这里研究的文件是/drivers/video/fbmem.c,该文件是一个lcd屏幕的驱动。

3.2 大概框架

       如图所示,fb_mem.ko插入到操作系统中时,会向字符设备驱动管理子系统注册获得设备号并纳入到该管理系统中,顶层用户通过操作设备文件fb0则可以通过驱动控制底层的显存,然后作用的效果会显示到LED屏幕上。

3.3 源码解析

按照初级设备驱动框架阅读了fbmem.c的部分代码。

入口函数fbmem_init:

可见这里创建了一个.proc文件,注册了一个字符型设备fb,这里使用的是静态注册的方法,因此固定主设备号为FB_MAJOR这个宏对应的整形数字,然后创建一个描述fb的设备类graphics,最后则是一个容错处理。

出口函数fbmem_exit:

       出口函数与入口函数对应,销毁了创建的.proc文件、graphics设备类和fb设备。

fb文件打开函数fb_open:

       首先在对应的模块被激活之后,根据次设备号拿到fb_info结构体的地址然后上锁,然后执行fb_open指向的函数。该驱动的源码中,操作fb_info结构体往往要先上锁,在操作结束后会开锁,这样做是为了避免冲突,也就是显存被多个进程同时操作。

获取fb_info结构体地址的函数get_fb_info:

       fb_open的主要任务是根据次设备号获取对应的fb_info结构体,后面的read、write等操作都是围绕fb_info结构体展开,而且这个也是framebuffer子系统的核心结构体。从这个函数可以看出,fb设备由一个数组进行管理,其数组对应的下标就是fb设备的次设备号,因此可以通过次设备找到数组里面对应下标指向的fb_info结构体的指针。

读操作函数fb_read:

写操作函数fb_write:

       fb_read和fb_write的代码思路基本相同,核心的部分都是先将读写的数据送到内核创建的buffer中,然后读取到用户的缓冲区或者写入framebuffer中。从源码可以看出,数据的读写是以页为单位的。容错处理主要是避免指针越界,偏转超出framebuffer的范围。此外,读写操作都执行了info->fbops->fb_sync,应该是用于同步的代码,确保帧缓冲设备上的所有更改都已同步到硬件上,读操作还执行了info->fbops->fb_read指向的函数,写操作则执行了info->fbops->fb_write指向的函数。

  • 13
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值