Framebuffer

什么是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

 

 

 

帧缓冲设备驱动的结构

我们知道在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的使用步骤

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

 

 

Framebuffer数据结构

kernel\include\linux\fb.h

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

 

struct fb_info {
    atomic_t count;
    int node;  /*一个FrameBuffer设备的次设备号*/
    int flags;
    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 */
    struct mutex bl_curve_mutex;    
    u8 bl_curve[FB_BACKLIGHT_LEVELS];
#endif
#ifdef CONFIG_FB_DEFERRED_IO
    struct delayed_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    1
    u32 state;            /* Hardware state i.e suspend */
    void *fbcon_par;    /* fbcon use-only private area */
    void *par;
    struct apertures_struct {
        unsigned int count;
        struct aperture {
            resource_size_t base;
            resource_size_t size;
        } ranges[0];
    } *apertures;
};

 

 

 

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驱动分析

1. s3cfb.c

 

 

2. s3c_device_fb

 

 

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驱动程序分析 https://blog.csdn.net/yangwen123/article/details/12096483

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

posted @ 2021-12-29 17:28  青山牧云人  阅读(5054)  评论(0编辑  收藏  举报