linux驱动之framebuffer

第一部分   framebuffer 概念介绍

1、framebuffer帧缓冲

  帧缓冲(framebuffer)是Linux系统为显示设备提供的一个接口,它将显示缓冲区抽象,屏蔽图像硬件的底层差异,允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。用户不必关心物理显示缓冲区的具体位置及存放方式,这些都是由帧缓冲设备驱动本身来完成。

  framebuffer机制模仿显卡的功能,将显卡硬件结构抽象为一系列的数据结构,可以通过对framebuffer的读写直接对显存进行操作。用户可以将framebuffer看成是显卡的一个映像,将其映射到进程空间后,就可以直接读写操作,写操作会直接反映在屏幕上。

  framebuffer是一个字符设备,主设备号是29,对应于/dev/fb%d设备文件。通常,使用如下方式(数字代表次设备号)

  0 =  /dev/fb0  第一个fb设备

  1 =  /dev/fb1  第二个fb设备

  fb也是一种普通的内存设备,可以读写其内容。例如,屏幕抓屏:cp /dev/fb0 myfilefb   虽然可以向内存设备(/dev/mem)一样,对其read、write、seek以及mmap。但区别在于fb使用的不是整个内存区。而是显存部分。

 

2、fb与应用程序的互交

  对于应用程序而言,它和其它的设备并没有什么区别,用户可以把fb看成是一块内存,既可以向内存中写数据,也可以读数据。fb的显示缓冲区位于内核空间。应用程序可以把此空间映射到自己的用户空间,再进行操作。

  在应用程序中,操作/dev/fbn的一般步骤如下:

  (1)打开/dev/fbn设备文件。

  (2)用ioctl()操作取得当前显示屏幕的参数,如屏幕的分辨率、每个像素点的比特数。根据屏幕的参数可计算屏幕缓冲区的大小。

  (3)用mmap()函数,将屏幕缓冲区映射到用户空间。

  (4)映射后就可以直接读/写屏幕缓冲区,进行绘图和图片显示。

第二部分  framebuffer数据结构分析 

     

  

   framebuffer涉及的数据结构如下:

  (1)struct  fb_info 

   一个帧缓冲区对应一个struct fb_info结构,它包括了帧缓冲设备的属性和操作的完整集合,每个帧设备都有一个fb_info结构体。

  (2)struct  fb_ops

    结构体用来实现对帧缓冲设备的操作,这些函数需要驱动开发人员编写,

  (3)struct  fb_fix_screeninfo

      该结构体记录了用户不能修改的固定显示控制器参数。这些固定的参数如缓冲区的物理地址、缓冲区的长度等等。

  (4)struct  fb_var_screeninfo

    结构体中存储了用户可以修改的显示器控制参数,例如屏幕分辨率、透明度等等。

  (5)struct  fb_cmap

    结构体中记录了颜色板信息,即调色板信息。,用户空间可以通过ioctl()的FBIOGETCMAP和 FBIOPUTCMAP命令读取或设定颜色表。
  

  以上结构体的关系如下:

(6)struct fb_bitfield

  结构体描述每一像素显示缓冲区的组织方式,包含位域偏移、位域长度和MSB 指示。

 

第三部分 framebuffer核心层框架分析

  framebuffer设备在Linux中是以平台设备形式存在的,fb设备驱动核心层为上层提供了系统调用,为底层驱动提供了接口,核心层的主文件及其功能如下。
  (1)drivers/video/fbmem.c。主要任务:1、创建graphics类、注册FB的字符设备驱动、提供register_framebuffer接口给具体framebuffer驱动编写着来注册fb设备的。本文件相对于fb来说,地位和作用和misc.c文件相对于杂散类设备来说一样的,结构和分析方法也是类似的。
  (2)drivers/video/fbsys.c。这个文件是处理fb在/sys目录下的一些属性文件的。
  (3)drivers/video/modedb.c。这个文件是管理显示模式(譬如VGA、720P等就是显示模式)的
  (4)drivers/video/fb_notify.c

 

  fbmem_init函数
  (1)#ifdef MODULE
  (2)fb_proc_fops和fb在proc文件系统中的表现
  (3)register_chrdev注册fb设备
  (4)class_create创建graphics类
  (5)fbmem_exit的对应
  fb_fops
  (1)为应用层实现read/write/mmap/ioctl在驱动层的接口
  (2)registered_fb和num_registered_fb
  (3)struct fb_info  register_framebuffer函数

  (1)fb驱动框架开放给驱动编写着的注册接口
  (2)fb_check_foreignness
  (3)remove_conflicting_framebuffers
  (4)device_create
  (5)fb_init_device

  fb在sysfs中的接口
  (1)device_attrs
  (2)dev_set_drvdata和dev_get_drvdata

  注册登记该fb设备
  (1)registered_fb[i] = fb_info;
  (2)结合fb_read等函数中对fb_info的使用
  (3)关键点:数据如何封装、数据由谁准备由谁消费、数据如何传递

 

第四部分 framebuffer驱动层分析

  驱动层涉及源码文件:

  (1)drivers/video/samsung/s3cfb.c,驱动主体,主要是处理和数据结构有关的
  (2)drivers/video/samsung/s3cfb_fimd6x.c,里面有很多LCD硬件操作的函数,主要是处理和硬件有关的
  (2)arch/arm/mach-s5pv210/mach-x210.c,负责提供platform_device的
  (3)arch/arm/plat-s5p/devs.c,为platform_device提供一些硬件描述信息

  s3cfb.c文件probe函数分析

  (1)struct s3c_platform_fb *pdata;

  struct s3c_platform_fb 这个结构体是fb的platform_data结构体,这个结构体变量就是platform设备的私有数据,这个数据在platform_device.device.platform_data中存储。在mach文件中去准备并填充这些数据,在probe函数中通过传参的platform_device指针取出来。

  (2)struct s3cfb_global 这个结构体主要作用是在驱动部分的2个文件(s3cfb.c和s3cfb_fimd6x.c)的函数中做数据传递用的。
  (3)struct resource
  (4)regulator

   

  mach-x210.c文件分析

  smdkc110_machine_init函数里面主要是做了一些该平台下数据的初始化,里面涉及fb的由两个部分,如下:

  (1)platform_add_devices(smdkc110_devices, ARRAY_SIZE(smdkc110_devices));  //存放平台数据

        smdkc110_devices

          s3c_device_fb

  (2)s3cfb_set_platdata(&ek070tn93_fb_data);  //主要是用于提供设置GPIO的函数

 

 

 

第五部分 修改内核logo

  1、找一个需要显示的logo的png格式的图片(图片分辨率不得大于屏幕分辨率),并将其命令为logo.png

  2、在终端下执行以下命令

    pngtopnm logo.png | ppmquant -fs 224 | pnmtoplainpnm > logo_linux_clut224.ppm

  3、将生成的ppm文件拷贝到替换掉/root/porting_x210/kernel/x210kernel/drivers/video/logo/目录下

    并将其改名为logo_x210_clut224.ppm

  4、make

 备注:

 (1)修改fbmem.c的471行可以修改Logo显示的位置,例如,显示在屏幕中间:

    image.dx = (info->var.xres - logo->width)/2;
    image.dy = (info->var.yres - logo->height)/2;

 (2)如果图片显示不出来可能有以下原因

    a、内核里framebuffer的分辨率不对,可以在mach-x210.c的225行修改(1024 * 600);

    b、只能在左上角显示,CONFIG_FRAMEBUFFER_CONSOLE宏可能被选中(该宏不需要勾选,可以现在.config里面查看,确定后,make menuconfig 去除)

 

posted @ 2018-12-16 16:58  ZQ_One  阅读(7700)  评论(0编辑  收藏  举报