Framebuffer

摘要:
有一种说法是操纵lcd显示就是操纵framebuffer,表面上来看是这样的。那么framebuffer也是一个文件,比如/dev/fb0。这里的framebufferdev实际上就是前文讲的是一个抽象的设备。接下来就需要打通从framebufferdev到具体设备的通路,也就是framebufferdriver--˃LCDdriver,实际上就是把framebufferdriver的fb_ops对应到lcd_ops。Framebuffer的使用步骤打开设备文件/dev/fb0获取当前设备信息#includemmap做映射填充framebufferFramebuffer数据结构kernel\include\linux\fb.hfb_info是Linux为帧缓冲设备定义的驱动层接口。

什么是framebuffer

framebuffer从字面上理解是“帧缓冲”,一般有如下理解:

  • 单纯的把framebuffer看作一块内存,这部分内存包含了将要scan out显示的数据。
  • 等价于framebuffer driver。通常作为LCD控制器或者其他显示设备的驱动,FrameBuffer驱动是一个字符设备,设备节点是/dev/fbX,主设备号为29,次设备号递增,用户可以将Framebuffer看成是显示内存的一个映像,将其映射到进程地址空间之后,就可以直接进行读写操作,而写操作可以立即反应在屏幕上。这种操作是抽象的,统一的。用户不必关心物理显存的位置、换页机制等等具体细节。这些都是由Framebuffer设备驱动来完成的。Framebuffer设备为上层应用程序提供系统调用,也为下一层的特定硬件驱动提供接口;那些底层硬件驱动需要用到这儿的接口来向系统内核注册它们自己。所以可以看成是一个graphic hardware-independent抽象层,上面对接应用层,下面对接LCD等硬件的驱动。
  • 有一种说法是操纵lcd显示就是操纵framebuffer,表面上来看是这样的。实际上是frambuffer就是linux内核驱动申请的一片内存空间,然后lcd内有一片sram,cpu内部有个lcd控制器,它有个单独的dma用来将frambuffer中的数据拷贝到lcd的sram中去 拷贝到lcd的sram中的数据就会显示在lcd上,LCD驱动和framebuffer驱动没有必然的联系,它只是驱动LCD正常工作的,比如有信号传过来,那么LCD驱动负责把信号转成显示屏上的内容,至于什么内容这就是应用层要处理的。
    •   framebuffer帧缓冲(简称fb)是linux内核中虚拟出的一个设备
    •   framebuffer向应用层提供一个统一标准接口的显示设备
    •   从驱动来看,fb是一个典型的字符设备,而且创建了一个类/sys/class/graphics

Framebuffer第1张

帧缓冲设备驱动的结构

我们知道在Linux中,万物都是文件。那么framebuffer也是一个文件,比如/dev/fb0。我们只需要操作/dev/fb0就可以把图像显示在显示器上了,那么这是怎么实现的呢?

先谈谈如何把文件操作和设备操作关联起来。

物理层面:

Linux中的PCI设备可以将其控制寄存器映射到物理内存空间,而后,对这些控制寄存器的访问变成了对理内存的访问,因此,这些寄存器又被称为"memio"。一旦被映射到物理内存,Linux的普通进程就可以通过mmap将这些内存I/O映射到进程地址空间,这样就可以直接访问这些寄存器了。

逻辑层面:

FrameBuffer设备属于字符设备,采用了文件层—驱动层的接口方式,Linux为帧缓冲设备定义了驱动层的接口fb_info结构,在文件层上,用户调用file_operations的函数操作,间接调用fb_info中的fb_ops函数集来操作硬件。

这里的意思是说,对于Linux系统,其事先规定了对于文件的操作,也就是上面说的file_operations函数。我们只需要让file_operations函数和fb_ops函数对应起来,就实现了文件 --> framebuffer driver的操作。这里的framebuffer dev实际上就是前文讲的是一个抽象(或者说是虚拟)的设备。接下来就需要打通从framebuffer dev到具体设备的通路,也就是framebuffer driver --> LCD driver,实际上就是把framebuffer driver的fb_ops对应到lcd_ops。至于lcd_ops到硬件,什么样的二进制代码传过去显示怎样的输出,就是具体硬件厂商的人员所需要去实现的driver。

Framebuffer第2张

Framebuffer第3张

Framebuffer的使用步骤

  1. 打开设备文件 /dev/fb0
  2. 获取当前设备信息 #include <linux/fb.h>
  3. mmap做映射
  4. 填充framebuffer

Framebuffer数据结构

kernel\include\linux\fb.h

fb_info是Linux为帧缓冲设备定义的驱动层接口。它不仅包含了底层函数,而且还有记录设备状态的数据。每个帧缓冲设备都与一个fb_info结构相对应。

structfb_info {
    atomic_t count;
    int node;  /*一个FrameBuffer设备的次设备号*/
    intflags;
    struct mutex lock;        /*Lock for open/release/ioctl funcs */
    struct mutex mm_lock;        /*Lock for fb_mmap and smem_* fields */
    struct fb_var_screeninfo var;/*Current var */
    struct fb_fix_screeninfo fix;/*Current fix */
    struct fb_monspecs monspecs;/*Current Monitor specs */
    struct work_struct queue;    /*Framebuffer event queue */
    struct fb_pixmap pixmap;    /*Image hardware mapper */
    struct fb_pixmap sprite;    /*Cursor hardware mapper */
    struct fb_cmap cmap;        /*Current cmap */
    struct list_head modelist;  /*mode list */
    struct fb_videomode *mode;    /*current mode */#ifdef CONFIG_FB_BACKLIGHT
    struct backlight_device *bl_dev;
    /*Backlight level curve */
    structmutex bl_curve_mutex;    
    u8 bl_curve[FB_BACKLIGHT_LEVELS];
#endif#ifdef CONFIG_FB_DEFERRED_IO
    structdelayed_work deferred_work;
    struct fb_deferred_io *fbdefio;
#endif
    struct fb_ops *fbops;
    struct device *device;    /*This is the parent */
    struct device *dev;        /*This is this fb device */
    int class_flag;         /*private sysfs flags */#ifdef CONFIG_FB_TILEBLITTING
    struct fb_tile_ops *tileops;/*Tile Blitting */
#endif
    char __iomem *screen_base;    /*Virtual address */unsigned long screen_size;    /*Amount of ioremapped VRAM or 0 */ 
    void *pseudo_palette;        /*Fake palette of 16 colors */ 
#define FBINFO_STATE_RUNNING    0
#define FBINFO_STATE_SUSPENDED    1u32 state;            /*Hardware state i.e suspend */
    void *fbcon_par;    /*fbcon use-only private area */
    void *par;
    structapertures_struct {
        unsigned intcount;
        structaperture {
            resource_size_t base;
            resource_size_t size;
        } ranges[0];
    } *apertures;
};

Framebuffer第4张

framebuffer驱动源码分析

1. 驱动框架部分,即framebuffer driver相关

  • drivers/video/fbmem.c主要任务:fbmen_init()函数负责创建graphics类、注册FB的字符设备驱动、register_framebuffer()函数提供接口给具体framebuffer驱动编写着来注册fb设备。本文件相对于fb来说,地位和作用和misc.c文件相对于杂散类设备来说一样的,结构和分析方法也是类似的。
  • drivers/video/fbsys.c这个文件是处理fb在/sys目录下的一些属性文件的。
  • drivers/video/modedb.c这个文件是管理显示模式(譬如VGA、720P等就是显示模式)的。
  • drivers/video/fb_notify.c这个文件是frame buff用来管理相关通知的。

2. 驱动部分, 即lcd driver相关,以三星s3fdb为例,读者没有此driver可以分析amdgpu driver

  • drivers/video/samsung/s3cfb.c驱动主体
  • drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c : 驱动主体

framebuffer驱动框架分析

Linux内核已经给我们封装了LCD驱动的抽象层,我们只需要调用内核封装的注册接口去实现我们的平台驱动即可。

  • 内核已经给我们封装了LCD驱动的抽象层是在fbmem.c,先简单分析一下它的框架。

Framebuffer第5张

  • 总结

Framebuffer第6张

framebuffer驱动分析

1. s3cfb.c

Framebuffer第7张

2. s3c_device_fb

Framebuffer第8张

3. probe函数

  • struct s3c_platform_fb :这个结构体是fb的platform_data结构体,这个结构体变量就是platform设备的私有数据,这个数据在platform_device.device.platform_data中存储。在mach文件中去准备并填充这些数据,在probe函数中通过传参的platform_device指针取出来。
  • struct s3cfb_global: 这个结构体主要作用是在驱动部分的2个文件(s3cfb.c和s3cfb_fimd6x.c)的函数中做数据传递用的。

Framebuffer第9张

Framebuffer第10张

Framebuffer第11张

参考链接:

FrameBuffer驱动程序分析https://blog.csdn.net/yangwen123/article/details/12096483

Linux驱动开发(9)------- framebuffer驱动详解https://blog.csdn.net/qq_45544223/article/details/106598190

免责声明:文章转载自《Framebuffer》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇dedecms 空间迁移步骤Redis内存碎片率下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

stm32的fsmc

   液晶估计也就只能白话这么一点了。      Fsmc是stm32一种新型的存储器拓展技术,可根据系统的应用需要,方便的进行不同类型大容量静态存储器的拓展。      Fsmc芯片分为如下几个部分:     Fsmc能将AHB上的传输信号转换到适当的外部设备协议,从而完成相应的内存映射,fsmc管理的是stm32中60000000h到9fffffffh...

LCD时序中设计到的VSPW/VBPD/VFPD/HSPW/HBPD/HFPD总结【转】

转自:https://blog.csdn.net/u011603302/article/details/50732406 下面是我在网上摘录的一些关于LCD信号所需时钟的一些介绍, 描述方式一: 来自:http://www.cnblogs.com/mengfanrong/p/3785559.html LCD一般须要三个时序信号:VSYNC、HSYNC和VC...

全志A33屏幕旋转(Android)

0x00 环境说明:所使用的开发板为锐尔威视的插针版A33_Vstar 屏幕是买的第三方的KD050FWFPA011-C009A,其中LCD驱动IC为ILI9806E 0x01 LCD驱动移植:关于LCD驱动程序的编写/移植参考以前的一篇文章:https://www.cnblogs.com/DarkBright/p/10769858.html 大致流程如下...

AWTK 中 LCD 接口的四种实现方式

LCD 接口的四种实现方式 LCD 是对显示设备的抽象,提供了基本的绘图函数。自己去实现 LCD 接口虽然不难,但是需要花费不少功夫,AWTK 提供了几种缺省的实现,利用这些缺省的实现,在移植到新的平台时,一般只需要很少的代码就行了。 下面我们介绍一下几种常见的 LCD 实现方式: 一、基于寄存器实现的 LCD 在低端的嵌入式平台上,内存只有几十 KB...

树莓派LCD显示器安装步骤

3.5inch RPi LCD (A) 产品特点 硬件分辨率为480×320 电阻式触摸控制 兼容并可直接插入任何版本树莓派 提供驱动(支持RaspbianUbuntuKali和Retropie系统) 支持FBCP软件驱动,可设置软件分辨率和双屏显示 和你的树莓派一样大 沉金工艺,精雕细琢 快速入门 硬件连接 连接GPIO接口,Raspberry Pi...

Barebox for Tiny6410(LCD驱动移植)

一、目的 熟悉Barebox的Frame buffer框架、LCD驱动的移植和测试命令的编写。 二、主要内容 1.1 为Barebox移植基于Tiny6410的LCD驱动。 1.2 编写lcd命令测试LCD驱动。 1.3 编写rz命令,使得支持通过串口下载文件到内存。 1.4 增加支持直接对内存中的图片数据渲染到LCD上(Barebox本身只支持对图片文件...