• 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

  • 相关阅读:
    send和sendmsg性能测试【sendmsg和send的性能基本一样,并没有得到优化】
    send和sendmsg性能测试
    SparkException: Master removed our application
    大数据入门:各种大数据技术介绍
    78 subsets
    C、C ++的内存模型
    将博客搬至CSDN
    适配器模式
    建造者(Builder)模式
    桥接模式
  • 原文地址:https://www.cnblogs.com/ArsenalfanInECNU/p/15745877.html
Copyright © 2020-2023  润新知