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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM