在分析驅動之前,首先先了解幾個LCD驅動中的幾個重要的數據結構,
1、struct fb_info數據結構(FBI)
1 struct fb_info
2 {
3 int node;
4 int flags;
5 struct fb_var_screeninfo var; /*可變參數 */
6 struct fb_fix_screeninfo fix; /*固定參數 */
7 struct fb_monspecs monspecs; /*顯示器標準 */
8 struct work_struct queue; /* 幀緩衝事件隊列 */
9 struct fb_pixmap pixmap; /* 圖像硬件mapper */
10 struct fb_pixmap sprite; /* 光標硬件mapper */
11 struct fb_cmap cmap; /* 目前的顏色表*/
12 struct list_head modelist;
13 struct fb_videomode *mode; /* 目前的video模式 */
14
15 #ifdef CONFIG_FB_BACKLIGHT
16 struct mutex bl_mutex;
17 /* 對應的背光設備 */
18 struct backlight_device *bl_dev;
19 /* 背光調整 */
20 u8 bl_curve[FB_BACKLIGHT_LEVELS];
21 #endif
22
23 struct fb_ops *fbops; /* fb_ops,幀緩衝操作 */
24 struct device *device;
25 struct class_device *class_device; /
26 int class_flag; /* 私有sysfs標誌 */
27 #ifdef CONFIG_FB_TILEBLITTING
28 struct fb_tile_ops *tileops; /* 圖塊Blitting */
29 #endif
30 char _ _iomem *screen_base; /* 虛擬基地址 */
31 unsigned long screen_size; /* ioremapped的虛擬內存大小 */
32 void *pseudo_palette; /* 僞16色顏色表 */
33 #define FBINFO_STATE_RUNNING 0
34 #define FBINFO_STATE_SUSPENDED 1
35 u32 state; /* 硬件狀態,如掛起 */
36 void *fbcon_par;
37 void *par;
38 };
FBI 中記錄了幀緩衝設備的全部信息,包括設備的設置參數、狀態以及操作函數指針。每一個幀緩衝設備都必須對應一個 FBI。
2.fb_ops結構體
FBI 的成員變量 fb_ops 爲指向底層操作的函數的指針,這些函數是需要驅動程序開發人員編寫的。
1 struct fb_ops
2 {
3 struct module *owner;
4 /* 打開/釋放 */
5 int(*fb_open)(struct fb_info *info, int user);
6 int(*fb_release)(struct fb_info *info, int user);
7
8 /* 對於非線性佈局的/常規內存映射無法工作的幀緩衝設備需要 */
9 ssize_t(*fb_read)(struct file *file, char _ _user *buf, size_t
count,
10 loff_t*ppos);
11 ssize_t(*fb_write)(struct file *file, const char _ _user *buf,
size_t count,
12 loff_t *ppos);
13
14 /* 檢測可變參數,並調整到支持的值*/
15 int(*fb_check_var)(struct fb_var_screeninfo *var, struct
fb_info *info);
16
17 /* 根據info->var設置video模式 */
18 int(*fb_set_par)(struct fb_info *info);
19
20 /* 設置color寄存器 */
21 int(*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
unsigned
22 blue, unsigned transp, struct fb_info *info);
23
24 /* 批量設置color寄存器,設置顏色表 */
25 int(*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);
26
27 /*顯示空白 */
28 int(*fb_blank)(int blank, struct fb_info *info);
29
30 /* pan顯示 */
31 int(*fb_pan_display)(struct fb_var_screeninfo *var, struct
fb_info *info);
32
33 /* 矩形填充 */
34 void(*fb_fillrect)(struct fb_info *info, const struct
fb_fillrect *rect);
35 /* 數據複製 */
36 void(*fb_copyarea)(struct fb_info *info, const struct
fb_copyarea *region);
37 /* 圖形填充 */
38 void(*fb_imageblit)(struct fb_info *info, const struct fb_image
*image);
39
40 /* 繪製光標 */
41 int(*fb_cursor)(struct fb_info *info, struct fb_cursor *cursor);
42
43 /* 旋轉顯示 */
44 void(*fb_rotate)(struct fb_info *info, int angle);
45
46 /* 等待blit空閒 (可選) */
47 int(*fb_sync)(struct fb_info *info);
48
49 /* fb特定的ioctl (可選) */
50 int(*fb_ioctl)(struct fb_info *info, unsigned int cmd, unsigned
long arg);
51
52 /* 處理32位的compat ioctl (可選) */
53 int(*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
unsigned long arg);
54
55 /* fb特定的mmap */
56 int(*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
57
58 /* 保存目前的硬件狀態 */
59 void(*fb_save_state)(struct fb_info *info);
60
61 /* 恢復被保存的硬件狀態 */
62 void(*fb_restore_state)(struct fb_info *info);
63 };
LCD驅動中比較關鍵的是framebuff(幀緩衝)
FrameBuffer的原理
FrameBuffer 是出現在 Linux內核當中的一種驅動程序接口。它是Linux內核抽象出來的設備,供用戶態進程實現直接寫屏。Framebuffer機制模仿顯卡的功能,將顯卡硬件結構抽象掉,可以通過Framebuffer的讀寫直接對顯存進行操作。用戶可以將Framebuffer看成是顯示內存的一個映像,將其映射到進程地址空間之後,就可以直接進行讀寫操作,而寫操作可以立即反應在屏幕上。這種操作是抽象的,統一的。用戶不必關心物理顯存的位置、換頁機制等等具體細節,這些都是由Framebuffer設備驅動來完成的。但Framebuffer本身不具備任何運算數據的能力,就只好比是一個暫時存放水的水池.CPU將運算後的結果放到這個水池,水池再將結果流到顯示器.中間不會對數據做處理. 應用程序也可以直接讀寫這個水池的內容.在這種機制下,儘管Framebuffer需要真正的顯卡驅動的支持,但所有顯示任務都有CPU完成,因此CPU負擔很重。
framebuffer的設備文件一般是 /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時,Linux是將顯卡置於圖形模式下的.
在應用程序中,一般通過將 FrameBuffer 設備映射到進程地址空間的方式使用,比如下面的程序就打開 /dev/fb0 設備,並通過 mmap 系統調用進行地址映射,隨後用 memset 將屏幕清空(這裏假設顯示模式是 1024x768-8 位色模式,線性內存模式):
int fb;
unsigned char* fb_mem;
fb = open ("/dev/fb0", O_RDWR);
fb_mem = mmap (NULL, 1024*768, PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);
memset (fb_mem, 0, 1024*768); //這個命令應該只有在root可以執行
FrameBuffer 設備還提供了若干 ioctl 命令,通過這些命令,可以獲得顯示設備的一些固定信息(比如顯示內存大小)、與顯示模式相關的可變信息(比如分辨率、象素結構、每掃描線的字節寬度),以及僞彩色模式下的調色板信息等等。
--------------------------------------------------------------------------------------------------------------------------------------------------------
下面開始分析framebuff在Linux內核中的實現機制。
下班了,先簡要寫點,LCD驅動中有三個文件需要注意,
1、alps\xx\platform\mt\kernel\drivers\video\lcd_drv.c
2、alps\xx\source\kernel\drivers\video\xxfb.c
3、alps\kernel\driver\video\fbmem.c
fbmem.c 文件是原始內核中的文件,framebuff的核心文件,實現了framebuff驅動的註冊、卸載等函數,並且在這裏註冊了設備文件。
xxfb.c是xx平臺,LCD具體的framebuff驅動。通過調用fbmem.c中的framebuff的註冊與卸載函數來向系統註冊xx的fb驅動。
lcd_drv.c中實現了具體的硬件配置操作。ok啦。餓死了~~回去~~