FrameBuffer研究
生活随笔
收集整理的這篇文章主要介紹了
FrameBuffer研究
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一.使用基礎: ? 1. Linux是 工作在保護模式下,所以用戶態進程是無法象DOS那樣使用顯卡BIOS里提供的中斷調用來實現直接寫屏,Linux抽象出FrameBuffer這個設備 來供用戶態進程實現直接寫屏。對于用戶而言,framebuffer和/dev下面的其他設備沒有什么區別,用戶可以把framebuffer 看成一塊內存,既可以向這塊內存中寫入數據,也可以從這塊內存中讀取數據。在應用程序中,一般通過將 FrameBuffer 設備映射到進程地址空間的方式使用。 2.在這種機制下,盡管Framebuffer需要真正的顯卡驅動的支持,但所有顯示任務都有CPU完成,因此CPU負擔很重. 3.PCI 設 備可以將自己的控制寄存器映射到物理內存空間,而后,對這些控制寄存器的訪問,給變成了對物理內存的訪問。因此,這些寄存器又被稱為"memio"。一旦 被映射到物理內存,Linux 的普通進程就可以通過 mmap 將這些內存 I/O 映射到進程地址空間,這樣就可以直接訪問這些寄存器了。 4.幀緩沖設備屬于字符設備,采用了“文件層-驅動層”的接口方式。Linux為幀緩沖設備定義的驅動層接口為struct fb_info結構。在文件層次上,用戶調用struct file_operations的函數操作,其中間接調用struct fb_ops的函數來操作硬件.當向內核注冊FB設備的時候,也注冊了struct fb_ops的指針.當打開fb設備時,先調用fb_drivers[]的xxxfb_init()來初始化設備; 5.第一個被注冊的framebuffer的minor等于0,第二個被注冊的framebuffer的minor等于1,以此類推。如/dev/fb0,/dev/fb1。
可以用命令: #dd if=/dev/zero of=/dev/fb 清空屏幕.
如果顯示模式是1024x768-8 位色,用命令:$ dd if=/dev/zero of=/dev/fb0 bs=1024 count=768 清空屏幕
用命令: #dd if=/dev/fb of=fbfile ?可以將fb中的內容保存下來;
可以重新寫回屏幕: #dd if=fbfile of=/dev/fb
二.? framebuffer內部結構
Framebuffer對應的源文件在linux/drivers/video/目錄下。總的抽象設備文件為fbcon.c,在這個目錄下還有與各種顯卡驅動相關的源文件。FrameBuffer設備驅動基于如下文件:
1) linux/include/linux/fb.h定義一些變量結構和宏。
2) linux/drivers/video/fbmem.c實現設備入口和初始化。
3)xxxfb.c: 自己添加的設備驅動文件,如struct fb_info;實現入口點函數: xxxfb_init; xxxfb_setup;
??????? 1.首先是fb.h。framebuffer設備很大程度上依靠了下面數據結構。
1).Struct fb_var_screeninfo描述圖形卡的特性的。通常是被用戶設置的。
2).Struct fb_fix_screeninfo定義了圖形卡的硬件特性,是不能改變的。
3).Struct fb_cmap描述設備無關的顏色映射信息。可以通過FBIOGETCMAP和FBIOPUTCMAP 對應的ioctl操作設定或獲取顏色映射信息.
4).Struct fb_info定義了當前圖形卡framebuffer設備狀態,一個圖形卡可能有兩個framebuffer,在這種情況下,就需要兩個fb_info結構。這個結構是唯一在內核空間可見的。在這個結構中有一個fb_ops指針,指向驅動設備工作所需的函數集。
5).struct fb_ops用戶應用可以使用ioctl()系統調用來操作設備,這個結構就是用以支持ioctl()的這些操作的。(注: fb_ops結構與file_operations 結構不同,fb_ops是底層操作的抽象,而file_operations是提供給上層系統調用的接口,可以直接調用.)ioctl()系統調用在文件 fbmem.c中實現,通過觀察可以發現ioctl()命令與fb_ops’s 中函數的關系:
FBIOGET_VSCREENINFO fb_get_var
FBIOPUT_VSCREENINFO fb_set_var
FBIOGET_FSCREENINFO fb_get_fix
FBIOPUTCMAP fb_set_cmap
FBIOGETCMAP fb_get_cmap
FBIOPAN_DISPLAY fb_pan_display
如果我們定義了fb_XXX_XXX 方法,用戶程序就可以使用FBIOXXXX宏的ioctl()操作來操作硬件。
2.其次是fbmem.c。fbmem.c 處于Framebuffer設備驅動技術的中心位置.它為上層應用程序提供系統調用也為下一層的特定硬件驅動提供接口;那些底層硬件驅動需要用到這兒的接口來向系統內核注冊它們自己. fbmem.c 為所有支持FrameBuffer的設備驅動提供了通用的接口.
1) 全局變量
struct fb_info *registered_fb[FB_MAX];
int num_registered_fb;
這兩變量記錄了所有fb_info 結構的實例,fb_info 結構描述顯卡的當前狀態,所有設備對應的fb_info 結構都保存在這個數組中,當一個FrameBuffer設備驅動向系統注冊自己時,其對應的fb_info 結構就會添加到這個結構中,同時num_registered_fb 為自動加1.
2)fbmem.c 實現了如下函數.
register_framebuffer(struct fb_info *fb_info);
unregister_framebuffer(struct fb_info *fb_info);
這兩個是提供給下層FrameBuffer設備驅動的接口,設備驅動通過這兩函數向系統注冊或注銷自己。幾乎底層設備驅動所要做的所有事情就是填充fb_info結構然后向系統注冊或注銷它。
??????? 3.xxxfb.c。自己添加的設備驅動文件,如以下等內容。
static struct fb_ops xxxfb_ops = {
owner: THIS_MODULE,
fb_open: xxxfb_open, /* only if you need it to do something */
fb_release: xxxfb_release, /* only if you need it to do something */
fb_get_fix: fbgen_get_fix,
fb_get_var: fbgen_get_var,
fb_set_var: fbgen_set_var,
fb_get_cmap: fbgen_get_cmap,
fb_set_cmap: fbgen_set_cmap,
fb_pan_display: fbgen_pan_display,
fb_ioctl: xxxfb_ioctl, /* optional */
};
?
三framebuffer驅動。
1.首先需要添加下面的代碼到fbmem.c
static struct {
const char *name;
int (*init)(void);
int (*setup)(char*);
} fb_drivers[] __initdata = {
#ifdef CONFIG_FB_YOURCARD?????????????? //紅色為添加部分
{ "driver_name", xxxfb_init, xxxfb_setup },
#endif
2.其次在xxxfb.c 中根據自己的需要重新分配顯存大小。例如:
?#define VIDEOMEMSIZE (1*1024*1024) /* 1 MB */
再次根據自己的硬件設備修改相應的var 信息。主要修改
xxxfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
????? 下面是函數fb_set_var()的執行步驟:
1)檢測是否必須設定模式
2)設定模式
3)設定顏色映射
4) 根據以前的設定重新設置LCD控制器的各寄存器。
四.配置添加驅動
1.make menuconfig時,首先進入Character devices,選中里面的Virtualterminal.如果希望控制臺在液晶上輸出,則選中Support for console on virtual terminal。
2.退到上一層界面我們就可以看到Console device 的選項,
進入后將光標落在Framebuffer Support 上,按回車鍵進入,在里面選擇自己所需要的framebuffer設備即可。
3.在Advanced low level 中可以配置bpp packed pixel support,然后選中Selectcompiled-in fonts 即可。
等操作系統運行以后就會在/dev下面看到fb 這個設備。它的major應該是29,第一個設備的minor應該是0。
五.其它
編譯內核時,選擇framebuffer模式,啟動時屏幕上有一企鵝圖片,不知這是如何造成的這個圖片可以去掉或改動嗎?
答:可以將drivers/video/fbcon.c: fbcon_setup()中if (logo) { } 代碼去掉。
可以用命令: #dd if=/dev/zero of=/dev/fb 清空屏幕.
如果顯示模式是1024x768-8 位色,用命令:$ dd if=/dev/zero of=/dev/fb0 bs=1024 count=768 清空屏幕
用命令: #dd if=/dev/fb of=fbfile ?可以將fb中的內容保存下來;
可以重新寫回屏幕: #dd if=fbfile of=/dev/fb
二.? framebuffer內部結構
Framebuffer對應的源文件在linux/drivers/video/目錄下。總的抽象設備文件為fbcon.c,在這個目錄下還有與各種顯卡驅動相關的源文件。FrameBuffer設備驅動基于如下文件:
1) linux/include/linux/fb.h定義一些變量結構和宏。
2) linux/drivers/video/fbmem.c實現設備入口和初始化。
3)xxxfb.c: 自己添加的設備驅動文件,如struct fb_info;實現入口點函數: xxxfb_init; xxxfb_setup;
??????? 1.首先是fb.h。framebuffer設備很大程度上依靠了下面數據結構。
1).Struct fb_var_screeninfo描述圖形卡的特性的。通常是被用戶設置的。
2).Struct fb_fix_screeninfo定義了圖形卡的硬件特性,是不能改變的。
3).Struct fb_cmap描述設備無關的顏色映射信息。可以通過FBIOGETCMAP和FBIOPUTCMAP 對應的ioctl操作設定或獲取顏色映射信息.
4).Struct fb_info定義了當前圖形卡framebuffer設備狀態,一個圖形卡可能有兩個framebuffer,在這種情況下,就需要兩個fb_info結構。這個結構是唯一在內核空間可見的。在這個結構中有一個fb_ops指針,指向驅動設備工作所需的函數集。
5).struct fb_ops用戶應用可以使用ioctl()系統調用來操作設備,這個結構就是用以支持ioctl()的這些操作的。(注: fb_ops結構與file_operations 結構不同,fb_ops是底層操作的抽象,而file_operations是提供給上層系統調用的接口,可以直接調用.)ioctl()系統調用在文件 fbmem.c中實現,通過觀察可以發現ioctl()命令與fb_ops’s 中函數的關系:
FBIOGET_VSCREENINFO fb_get_var
FBIOPUT_VSCREENINFO fb_set_var
FBIOGET_FSCREENINFO fb_get_fix
FBIOPUTCMAP fb_set_cmap
FBIOGETCMAP fb_get_cmap
FBIOPAN_DISPLAY fb_pan_display
如果我們定義了fb_XXX_XXX 方法,用戶程序就可以使用FBIOXXXX宏的ioctl()操作來操作硬件。
2.其次是fbmem.c。fbmem.c 處于Framebuffer設備驅動技術的中心位置.它為上層應用程序提供系統調用也為下一層的特定硬件驅動提供接口;那些底層硬件驅動需要用到這兒的接口來向系統內核注冊它們自己. fbmem.c 為所有支持FrameBuffer的設備驅動提供了通用的接口.
1) 全局變量
struct fb_info *registered_fb[FB_MAX];
int num_registered_fb;
這兩變量記錄了所有fb_info 結構的實例,fb_info 結構描述顯卡的當前狀態,所有設備對應的fb_info 結構都保存在這個數組中,當一個FrameBuffer設備驅動向系統注冊自己時,其對應的fb_info 結構就會添加到這個結構中,同時num_registered_fb 為自動加1.
2)fbmem.c 實現了如下函數.
register_framebuffer(struct fb_info *fb_info);
unregister_framebuffer(struct fb_info *fb_info);
這兩個是提供給下層FrameBuffer設備驅動的接口,設備驅動通過這兩函數向系統注冊或注銷自己。幾乎底層設備驅動所要做的所有事情就是填充fb_info結構然后向系統注冊或注銷它。
??????? 3.xxxfb.c。自己添加的設備驅動文件,如以下等內容。
static struct fb_ops xxxfb_ops = {
owner: THIS_MODULE,
fb_open: xxxfb_open, /* only if you need it to do something */
fb_release: xxxfb_release, /* only if you need it to do something */
fb_get_fix: fbgen_get_fix,
fb_get_var: fbgen_get_var,
fb_set_var: fbgen_set_var,
fb_get_cmap: fbgen_get_cmap,
fb_set_cmap: fbgen_set_cmap,
fb_pan_display: fbgen_pan_display,
fb_ioctl: xxxfb_ioctl, /* optional */
};
?
三framebuffer驅動。
1.首先需要添加下面的代碼到fbmem.c
static struct {
const char *name;
int (*init)(void);
int (*setup)(char*);
} fb_drivers[] __initdata = {
#ifdef CONFIG_FB_YOURCARD?????????????? //紅色為添加部分
{ "driver_name", xxxfb_init, xxxfb_setup },
#endif
2.其次在xxxfb.c 中根據自己的需要重新分配顯存大小。例如:
?#define VIDEOMEMSIZE (1*1024*1024) /* 1 MB */
再次根據自己的硬件設備修改相應的var 信息。主要修改
xxxfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
????? 下面是函數fb_set_var()的執行步驟:
1)檢測是否必須設定模式
2)設定模式
3)設定顏色映射
4) 根據以前的設定重新設置LCD控制器的各寄存器。
四.配置添加驅動
1.make menuconfig時,首先進入Character devices,選中里面的Virtualterminal.如果希望控制臺在液晶上輸出,則選中Support for console on virtual terminal。
2.退到上一層界面我們就可以看到Console device 的選項,
進入后將光標落在Framebuffer Support 上,按回車鍵進入,在里面選擇自己所需要的framebuffer設備即可。
3.在Advanced low level 中可以配置bpp packed pixel support,然后選中Selectcompiled-in fonts 即可。
等操作系統運行以后就會在/dev下面看到fb 這個設備。它的major應該是29,第一個設備的minor應該是0。
五.其它
編譯內核時,選擇framebuffer模式,啟動時屏幕上有一企鵝圖片,不知這是如何造成的這個圖片可以去掉或改動嗎?
答:可以將drivers/video/fbcon.c: fbcon_setup()中if (logo) { } 代碼去掉。
轉載于:https://blog.51cto.com/paullu/169803
總結
以上是生活随笔為你收集整理的FrameBuffer研究的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 正选择分析-PAML discussio
- 下一篇: fp16 fp32 int8