一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

framebuffer驅(qū)動全篇

 弓道自然_改名 2007-03-21
framebuffer驅(qū)動全篇
  

在后續(xù)的幾篇里面會詳細介紹如何編寫一個顯卡的驅(qū)動程序。
framebuffer device在內(nèi)核里面作為顯卡驅(qū)動模型,許多函數(shù)和數(shù)據(jù)結(jié)構(gòu)都是特定,正是這些特定的東西為我們的編程提供了方便。

要開發(fā)frame buffer device驅(qū)動,你應該閱讀Source\Source\Documentation\fb下面的說明文件,三個重要文件00-INDEX,framebuffer.txt,internals.txt,其他文件都是針對具體顯卡芯片的說明了。


文件00-INDEX譯文

文檔/documentation/fb的索引文件。如果你對frame buffer設備有什么想法,mail:Geert Uytterhoeven <geert@linux-m68k.org>

00-index 這個文件
framebuffer.txt--- frame buffer 設備介紹
internals.txt----frame buffer設備內(nèi)部快速瀏覽
modedb.txt----關于視頻模式的資料
aty128fb.txt----關于ATI Rage128顯卡的frame buffer設備
clgenfb.txt-----關于Cirrus Logic的顯卡
matroxfb.txt----關于Matrox的顯卡
pvr2fb.txt----關于PowerVR 2的顯卡
tgafb.txt----關于TGA(DECChip 21030)顯卡
vesafb.txt----關于VESA顯卡

幀緩沖設備(framebuffer.txt譯文)

維護: Geert Uytterhoeven

最后校正:   May 10, 2001

翻譯:good02xaut@hotmail.com

0.介紹

幀緩沖設備提供了顯卡的抽象描述。他同時代表了顯卡上的顯存,應用程序通過定義好的接口可以訪問顯卡,而不需要知道底層的任何操作。

 

該設備使用特殊的設備節(jié)點,通常位于/dev目錄,如/dev/fb*.

 

1.用戶角度的/dev/fb*

從用戶的角度看,幀緩沖設備和其他位于/dev下面的設備類似。他是一個字符設備,通常

主設備號是29,次設備號定義幀緩沖的個數(shù)。

 

通常,使用如下方式(前面的數(shù)字代碼次設備號)

        0 = /dev/fb0    First frame buffer
        1 = /dev/fb1    Second frame buffer
      ...
        31 = /dev/fb31  32nd frame buffer

    

考慮到向下兼容,你可以創(chuàng)建符號鏈接:

      /dev/fb0current -> fb0
     /dev/fb1current -> fb1

and so on...

 

幀緩沖設備也是一種普通的內(nèi)存設備,你可以讀寫其內(nèi)容。例如,對屏幕抓屏:

  cp /dev/fb0 myfile

你也可以同時有多個顯示設備,例如你的主板上出了內(nèi)置的顯卡還有另一獨立的

顯卡。對應的幀緩沖設備(/dev/fb0 and /dev/fb1 etc.)可以獨立工作。

 

應用程序如 X server一般使用/dev/fb0作為默認的顯示幀緩沖區(qū)。你可以自定

把某個設備作為默認的幀緩沖設備,設置$FRAMEBUFFER環(huán)境變量即可。在sh/bash:

    export FRAMEBUFFER=/dev/fb1

在csh中:

    setenv FRAMEBUFFER /dev/fb1

   

設定后,X server將使用第二個幀緩沖區(qū)設備。

 

2.程序員角度看/dev/fb*

正如你所知,一個幀緩沖設備和內(nèi)存設備類似/dev/mem,并且有許多共性。你可以

read,write,seek以及mmap()。不同僅僅是幀緩沖的內(nèi)存不是所有的內(nèi)存區(qū),而是顯卡

專用的那部分內(nèi)存。

 

/dev/fb*也允許盡心ioctl操作,通過ioctl可以讀取或設定設備參數(shù)。顏色映射表

也是通過Ioctl設定。查看 就知道有多少ioctl應用以及相關數(shù)據(jù)結(jié)構(gòu)。

這里給出摘要:

 

  - 你可以獲取設備一些不變的信息,如設備名,屏幕的組織(平面,象素,...)對應內(nèi)存區(qū)

    的長度和起始地址。

  - 也可以獲取能夠發(fā)生變化的信息,例如位深,顏色格式,時序等。如果你改變這些值,

    驅(qū)動程序?qū)χ颠M行優(yōu)化,以滿足設備特性(返回EINVAL,如果你的設定,設備不支持)

  - 你也可以獲取或設定部分顏色表。

 

 所有這些特性讓應用程序十分容易的使用設備。X server可以使用/dev/fb*而不需知道硬件

 的寄存器是如何組織的。 XF68_FBDev是一個用于位映射(單色)X server,唯一要做的就是

 在應用程序在相應的位置設定是否顯示。

 

 在新內(nèi)核中,幀緩沖設備可以工作于模塊中,允許動態(tài)加載。這類驅(qū)動必須調(diào)用

 register_framebuffer()在系統(tǒng)中注冊。使用模塊更方便!

 

3.幀緩沖分辨率設定

 

幀緩沖的分辨率可以用工具fbset設定。他可以改變視頻設備的顯示模式。主要就是

改變當前視頻模式,如在啟動過程中,在/etc/rc.* 或 /etc/init.d/* 文件中調(diào)用,

可以把視頻模式從單色顯示變成真彩.

 

fbset使用存儲在配置文件中的視頻模式數(shù)據(jù)表,你可以在文件中增加自己需要的顯示模式。

 

4.X Server

 

X server (XF68_FBDev)是對幀緩沖設備的最主要應用。從XFree86  3.2后,X server就是

XFree86 的一部分了,有2個工作模式:

 

  - 在/etc/XF86Config文件中,如果`Display‘段關于 `fbdev‘的配置:

    Modes "default"

    X server 將使用前面討論的,從環(huán)境變量$FRAMEBUFFER獲取當前幀緩沖設備.
    你也可以設定顏色位深,使用Depth關鍵字,使用Virtual設定虛擬分辨率。這也是

    默認設置。
   

  - 然而你也可以通過設定/etc/XF86Config,改變分辨率。這樣有很多靈活性,唯一的

    不足就是你必須設定刷新頻率??梢杂胒bset -x

通過fbset或xvidtune切換顯示模式。

 

5.視頻模式頻率

 

CRT顯示器是用3個電子槍轟擊磷粉完成顏色的顯示的。

電子槍從左到右的水平掃描,并從上至下的垂直掃描。通過改變槍的電壓,所顯示的顏色

可以不同。

當電子槍完成一行掃描重新回到下一行的開始,被稱作“水平折回”。當一屏幕全部

掃描完畢,電子槍將回到最左上腳,被成為“垂直折回”。在折回的途中電子槍是關閉的。

 

電子槍打點的移動速度取決于點時鐘。如果點時鐘是28.37516 MHz,打一個點需要

35242 ps。

    1/(28.37516E6 Hz) = 35.242E-9 s

 

如果屏幕分辨率是640x480,那么一行的時間是:

        640*35.242E-9 s = 22.555E-6 s

然而水平折回也是需要時間的,通常272個打點時間,因此一行總共需要:

        (640+272)*35.242E-9 s = 32.141E-6 s

我們就認為水平掃描的頻率是31KHz:      

        1/(32.141E-6 s) = 31.113E3 Hz

 

一屏幕含有480行,加上垂直折回時間49,一屏所需的時間:

        (480+49)*32.141E-6 s = 17.002E-3 s

我們就認為垂直掃描的頻率是59Hz:

        1/(17.002E-3 s) = 58.815 Hz

這也意味著屏幕數(shù)據(jù)每秒鐘刷新59次。為了得到穩(wěn)定的圖像顯示效果,VESA垂直掃描

頻率不低于72Hz。但是也因人而異,有些人50Hz感覺不到任何問題,有些至少在

80Hz以上才可以。

 

由于顯示器不知道什么時候新行開始掃描,顯卡為每一行掃描提供水平同步信號。

類似的,他也為每一幀顯示提供垂直同步信號。圖像在屏幕上點的位置取決于這些

同步信號的發(fā)生時刻。

 

下圖給出了所有時序的概要。水平折回的時間就是左邊空白+右邊空白+水平同步長度。

垂直折回的時間就是上空白+下空白+垂直同步長。     
  +----------+---------------------------------------------+----------+-------+
  |          |                ^                            |          |       |
  |          |                |upper_margin                |          |       |
  |          |                ?                           |          |       |
  +----------###############################################----------+-------+
  |          #                ^                            #          |       |
  |          #                |                            #          |       |
  |          #                |                            #          |       |
  |          #                |                            #          |       |
  |   left   #                |                            #  right   | hsync |
  |  margin  #                |       xres                 #  margin  |  len  |
  |<-------->#<---------------+--------------------------->#<-------->|<----->|
  |          #                |                            #          |       |
  |          #                |                            #          |       |
  |          #                |                            #          |       |
  |          #                |yres                        #          |       |
  |          #                |                            #          |       |
  |          #                |                            #          |       |
  |          #                |                            #          |       |
  |          #                |                            #          |       |
  |          #                |                            #          |       |
  |          #                |                            #          |       |
  |          #                |                            #          |       |
  |          #                |                            #          |       |
  |          #                ?                           #          |       |
  +----------###############################################----------+-------+
  |          |                ^                            |          |       |
  |          |                |lower_margin                |          |       |
  |          |                ?                           |          |       |
  +----------+---------------------------------------------+----------+-------+
  |          |                ^                            |          |       |
  |          |                |vsync_len                   |          |       |
  |          |                ?                           |          |       |
  +----------+---------------------------------------------+----------+-------+

  

6.把XFree86時序變成frame buffer device時序

典型的顯示模式:

  "800x600"     50      800  856  976 1040    600  637  643  666
 < name >     DCF       HR  SH1  SH2  HFL     VR  SV1  SV2  VFL  

 

 而幀緩沖設備使用下面的參數(shù):

  - pixclock: 點時鐘 in ps (pico seconds)
  - left_margin: time from sync to picture
  - right_margin: time from picture to sync
  - upper_margin: time from sync to picture
  - lower_margin: time from picture to sync
  - hsync_len: length of horizontal sync
  - vsync_len: length of vertical sync

 

1) Pixelclock:
   xfree: in MHz
   fb: in picoseconds (ps)

   pixclock = 1000000 / DCF

2) horizontal timings:
   left_margin = HFL - SH2
   right_margin = SH1 - HR
   hsync_len = SH2 - SH1

3) vertical timings:
   upper_margin = VFL - SV2
   lower_margin = SV1 - VR
   vsync_len = SV2 - SV1

 

更好的VESA的例子可以在XFree86的源碼中找到,

"xc/programs/Xserver/hw/xfree86/doc/modeDB.txt".

 

7. 引用

獲取更多關于幀緩沖設備以及應用的參考,請訪問:

    http:/linux-fbdev.sourceforge.net/

或者查閱下面的文檔:

  - The manual pages for fbset: fbset(8), fb.modes(5)
  - The manual pages for XFree86: XF68_FBDev(1), XF86Config(4/5)
  - The mighty kernel sources:
      o linux/drivers/video/
      o linux/include/linux/fb.h
      o linux/include/video/  

 

幀緩沖設備的內(nèi)部數(shù)據(jù)結(jié)構(gòu)(internals.txt)

Geert Uytterhoeven , 21 July 1998

翻譯:good02xaut@hotmail.com

       ××××幀緩沖設備中用到的結(jié)構(gòu)體××××

       

以下數(shù)據(jù)結(jié)構(gòu)在幀緩沖設備使用,定義        

 

1. Outside the kernel (user space)

  - struct fb_fix_screeninfo

    幀緩沖設備中設備無關的常值數(shù)據(jù)信息??梢酝ㄟ^Ioctl的FBIOGET_FSCREENINFO獲取。

  - struct fb_var_screeninfo

    幀緩沖設備中設備無關的變量數(shù)據(jù)信息和特定的顯示模式。可以通過iotcl的FBIOGET_VSCREENINFO

    獲取,并通過ioctl的FBIOPUT_VSCREENINFO設定。還有FBIOPAN_DISPLAY可以用。

  - struct fb_cmap

    設備無關的顏色表信息。你可以通過ioctl的FBIOGETCMAP 和 FBIOPUTCMAP讀取或設定。

   

2. Inside the kernel

  

 - struct fb_info

    常規(guī)信息,API以及幀緩沖設備的底層信息(主板地址...).

  - struct `par‘

    唯一指定該設備的顯示模式的設備相關信息。

  - struct display

    幀緩沖設備和控制臺驅(qū)動之間的接口。
--------------------------------------------------------------------------------

        ***  常用的幀緩沖 API  ***

Monochrome (FB_VISUAL_MONO01 and FB_VISUAL_MONO10)

-------------------------------------------------

每個象素是黑或白。

 

Pseudo color (FB_VISUAL_PSEUDOCOLOR and FB_VISUAL_STATIC_PSEUDOCOLOR)
---------------------------------------------------------------------

索引顏色顯示

 

True color (FB_VISUAL_TRUECOLOR)
--------------------------------

真彩顯示,分成紅綠蘭三基色

 

Direct color (FB_VISUAL_DIRECTCOLOR)
------------------------------------

每個象素顏色也是有紅綠藍組成,不過每個顏色值是個索引,需要查表。

 

Grayscale displays
------------------

灰度顯示,紅綠藍的值都一樣

 

準備開始寫我們自己的驅(qū)動之前,請詳細閱讀如下文件:

\Documentation\fb目錄  vesafb.txt,matroxfb.txt,sa1100fb.txt
\drivers\video目錄          fbmem.c,fbgen.c,fbmon.c,fbcmap.c
                                      skeletonfb.c
                                      vesafb.c,sa1100fb.c,sa1100fb.h

include\linux目錄            fb.h

最值得關注的是skeletonfb.c,該文件給出了一個fb device 驅(qū)動的框架

準備好了,就開始寫自己的fram buffer device driver:)
framebuffer驅(qū)動全篇(二)
    

還是要補充點,下面是/linux/fb.h的部分注釋,加粗的是常用的,紅色是關鍵的,一般不可少。旁邊沒有漢字,要么很簡單沒必要加注,要么就用不到!

注釋:good02xaut@hotmail.com

 

#ifndef _LINUX_FB_H

#define _LINUX_FB_H

 

#include

#include

 

/* Definitions of frame buffers                     */

 

#define FB_MAJOR        29  /*主設備號*/

#define FB_MAX          32  /* sufficient for now */

 

/* ioctls

   0x46 is ‘F‘                              */

#define FBIOGET_VSCREENINFO 0x4600

#define FBIOPUT_VSCREENINFO 0x4601

#define FBIOGET_FSCREENINFO 0x4602

#define FBIOGETCMAP     0x4604

#define FBIOPUTCMAP     0x4605

#define FBIOPAN_DISPLAY     0x4606

/* 0x4607-0x460B are defined below */

/* #define FBIOGET_MONITORSPEC  0x460C */

/* #define FBIOPUT_MONITORSPEC  0x460D */

/* #define FBIOSWITCH_MONIBIT   0x460E */

#define FBIOGET_CON2FBMAP   0x460F

#define FBIOPUT_CON2FBMAP   0x4610

#define FBIOBLANK       0x4611      /* arg: 0 or vesa level + 1 */

#define FBIOGET_VBLANK      _IOR(‘F‘, 0x12, struct fb_vblank)

#define FBIO_ALLOC              0x4613

#define FBIO_FREE               0x4614

#define FBIOGET_GLYPH           0x4615

#define FBIOGET_HWCINFO         0x4616

#define FBIOPUT_MODEINFO        0x4617

#define FBIOGET_DISPINFO        0x4618

 

 

#define FB_TYPE_PACKED_PIXELS       0   /* Packed Pixels    */

#define FB_TYPE_PLANES          1   /* Non interleaved planes */

#define FB_TYPE_INTERLEAVED_PLANES  2   /* Interleaved planes   */

#define FB_TYPE_TEXT            3   /* Text/attributes  */

#define FB_TYPE_VGA_PLANES      4   /* EGA/VGA planes   */

 

#define FB_AUX_TEXT_MDA     0   /* Monochrome text */

#define FB_AUX_TEXT_CGA     1   /* CGA/EGA/VGA Color text */

#define FB_AUX_TEXT_S3_MMIO 2   /* S3 MMIO fasttext */

#define FB_AUX_TEXT_MGA_STEP16  3   /* MGA Millenium I: text, attr, 14 reserved bytes */

#define FB_AUX_TEXT_MGA_STEP8   4   /* other MGAs:      text, attr,  6 reserved bytes */

 

#define FB_AUX_VGA_PLANES_VGA4      0   /* 16 color planes (EGA/VGA) */

#define FB_AUX_VGA_PLANES_CFB4      1   /* CFB4 in planes (VGA) */

#define FB_AUX_VGA_PLANES_CFB8      2   /* CFB8 in planes (VGA) */

 

#define FB_VISUAL_MONO01        0   /* Monochr. 1=Black 0=White */

#define FB_VISUAL_MONO10        1   /* Monochr. 1=White 0=Black */

#define FB_VISUAL_TRUECOLOR     2   /* True color   */

#define FB_VISUAL_PSEUDOCOLOR       3   /* Pseudo color (like atari) */

#define FB_VISUAL_DIRECTCOLOR       4   /* Direct color */

#define FB_VISUAL_STATIC_PSEUDOCOLOR    5   /* Pseudo color readonly */

 

#define FB_ACCEL_NONE       0   /* no hardware accelerator  */

#define FB_ACCEL_ATARIBLITT 1   /* Atari Blitter        */

#define FB_ACCEL_AMIGABLITT 2   /* Amiga Blitter                */

#define FB_ACCEL_S3_TRIO64  3   /* Cybervision64 (S3 Trio64)    */

#define FB_ACCEL_NCR_77C32BLT   4   /* RetinaZ3 (NCR 77C32BLT)      */

#define FB_ACCEL_S3_VIRGE   5   /* Cybervision64/3D (S3 ViRGE)  */

#define FB_ACCEL_ATI_MACH64GX   6   /* ATI Mach 64GX family     */

#define FB_ACCEL_DEC_TGA    7   /* DEC 21030 TGA        */

#define FB_ACCEL_ATI_MACH64CT   8   /* ATI Mach 64CT family     */

#define FB_ACCEL_ATI_MACH64VT   9   /* ATI Mach 64CT family VT class */

#define FB_ACCEL_ATI_MACH64GT   10  /* ATI Mach 64CT family GT class */

#define FB_ACCEL_SUN_CREATOR    11  /* Sun Creator/Creator3D    */

#define FB_ACCEL_SUN_CGSIX  12  /* Sun cg6          */

#define FB_ACCEL_SUN_LEO    13  /* Sun leo/zx           */

#define FB_ACCEL_IMS_TWINTURBO  14  /* IMS Twin Turbo       */

#define FB_ACCEL_3DLABS_PERMEDIA2 15    /* 3Dlabs Permedia 2        */

#define FB_ACCEL_MATROX_MGA2064W 16 /* Matrox MGA2064W (Millenium)  */

#define FB_ACCEL_MATROX_MGA1064SG 17    /* Matrox MGA1064SG (Mystique)  */

#define FB_ACCEL_MATROX_MGA2164W 18 /* Matrox MGA2164W (Millenium II) */

#define FB_ACCEL_MATROX_MGA2164W_AGP 19 /* Matrox MGA2164W (Millenium II) */

#define FB_ACCEL_MATROX_MGAG100 20  /* Matrox G100 (Productiva G100) */

#define FB_ACCEL_MATROX_MGAG200 21  /* Matrox G200 (Myst, Mill, ...) */

#define FB_ACCEL_SUN_CG14   22  /* Sun cgfourteen       */

#define FB_ACCEL_SUN_BWTWO  23  /* Sun bwtwo            */

#define FB_ACCEL_SUN_CGTHREE    24  /* Sun cgthree          */

#define FB_ACCEL_SUN_TCX    25  /* Sun tcx          */

#define FB_ACCEL_MATROX_MGAG400 26  /* Matrox G400          */

#define FB_ACCEL_NV3        27  /* nVidia RIVA 128              */

#define FB_ACCEL_NV4        28  /* nVidia RIVA TNT      */

#define FB_ACCEL_NV5        29  /* nVidia RIVA TNT2     */

#define FB_ACCEL_CT_6555x   30  /* C&T 6555x            */

#define FB_ACCEL_3DFX_BANSHEE   31  /* 3Dfx Banshee         */

#define FB_ACCEL_ATI_RAGE128    32  /* ATI Rage128 family       */

#define FB_ACCEL_IGS_CYBER2000  33  /* CyberPro 2000        */

#define FB_ACCEL_IGS_CYBER2010  34  /* CyberPro 2010        */

#define FB_ACCEL_IGS_CYBER5000  35  /* CyberPro 5000        */

#define FB_ACCEL_SIS_GLAMOUR    36  /* SiS 300/630/540              */

#define FB_ACCEL_3DLABS_PERMEDIA3 37    /* 3Dlabs Permedia 3        */

/*上面的宏定義不用關心*/

 

/*不可修改的屏幕信息,用戶空間可見*/

struct fb_fix_screeninfo {

    char id[16];         /* identification string eg "TT Builtin" */

    unsigned long smem_start;   /* Start of frame buffer mem 顯存的起始地址*/

                  /* (physical address) */

    __u32 smem_len;          /* Length of frame buffer mem 顯存的大小 */

    __u32 type;          /* see FB_TYPE_*     */

    __u32 type_aux;          /* Interleave for interleaved Planes */

    __u32 visual;        /* see FB_VISUAL_*       */

    __u16 xpanstep;          /* zero if no hardware panning  */

    __u16 ypanstep;          /* zero if no hardware panning  */

    __u16 ywrapstep;     /* zero if no hardware ywrap    */

    __u32 line_length;       /* length of a line in bytes  每行的字節(jié)數(shù)  */

    unsigned long mmio_start;   /* Start of Memory Mapped I/O   */

                  /* (physical address) */

    __u32 mmio_len;          /* Length of Memory Mapped I/O  */

    __u32 accel;           /* Type of acceleration available */

    __u16 reserved[3];       /* Reserved for future compatibility */

};

 

/* Interpretation of offset for color fields: All offsets are from the right,

 * inside a "pixel" value, which is exactly ‘bits_per_pixel‘ wide (means: you

 * can use the offset as right argument to <<). A pixel afterwards is a bit

 * stream and is written to video memory as that unmodified. This implies

 * big-endian byte order if bits_per_pixel is greater than 8.

 */

 /*像素所占字節(jié)內(nèi),各個顏色的位分配比如RGB=888,565,555等等,*/

struct fb_bitfield {

    __u32 offset;        /* beginning of bitfield */

    __u32 length;        /* length of bitfield       */

    __u32 msb_right;     /* != 0 : Most significant bit is */

                  /* right */

};

 

/*下面的宏也不常用*/

#define FB_NONSTD_HAM       1   /* Hold-And-Modify (HAM)        */

 

#define FB_ACTIVATE_NOW     0   /* set values immediately (or vbl)*/

#define FB_ACTIVATE_NXTOPEN 1   /* activate on next open    */

#define FB_ACTIVATE_TEST    2   /* don‘t set, round up impossible */

#define FB_ACTIVATE_MASK       15

                    /* values           */

#define FB_ACTIVATE_VBL        16   /* activate values on next vbl  */

#define FB_CHANGE_CMAP_VBL     32   /* change colormap on vbl   */

#define FB_ACTIVATE_ALL        64   /* change all VCs on this fb    */

 

#define FB_ACCELF_TEXT      1   /* text mode acceleration */

 

#define FB_SYNC_HOR_HIGH_ACT    1   /* horizontal sync high active  */

#define FB_SYNC_VERT_HIGH_ACT   2   /* vertical sync high active    */

#define FB_SYNC_EXT     4   /* external sync        */

#define FB_SYNC_COMP_HIGH_ACT   8   /* composite sync high active   */

#define FB_SYNC_BROADCAST   16  /* broadcast video timings

 

 

Framebuffer驅(qū)動程序模型

 

  下圖會向你展示目前的framebuffer設備驅(qū)動的結(jié)構(gòu),最常用的是非標準驅(qū)動。很明顯他所處的層次最高,程序編寫是最容易的。

理解了這個圖的,你已經(jīng)很輕松的去完成一個fb驅(qū)動,比如給sa1100,s2410,s2440系列的ARMLCD控制器寫驅(qū)動。

framebuffer驅(qū)動全篇(三)
  

Color Map 剖析

framebuffer驅(qū)動程序設計中,cmap這個東東太暈了?,F(xiàn)在我要把他赤裸裸的剖析給大家:)

1. struct fb_cmap

 


/*顏色映射表*/

struct fb_cmap {

       __u32 start;                  /* First entry   */

       __u32 len;                    /* Number of entries */

       __u16 *red;                  /* 紅色   */

       __u16 *green;               /*綠色*/

       __u16 *blue;                 /*藍色*/

       __u16 *transp;                     /* 透明度,允許 NULL */

};

該結(jié)構(gòu)在fb.h文件中定義,在struct fb_ops結(jié)構(gòu)中有兩個成員函數(shù)與其相關:

    /*獲取顏色表*/

    int (*fb_get_cmap)(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info);

    /*設定顏色表*/

    int (*fb_set_cmap)(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info);

 

struct fb_info結(jié)構(gòu)中有變量:

  struct fb_cmap cmap;                 /* Current cmap */

 

fpgen基礎操作下提供:

extern int fbgen_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info);

extern int fbgen_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info);

 

 

 

在文件/* drivers/video/fbcmap.c */中提供更多的cmap應用

extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);

extern void fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto);

extern int fb_get_cmap(struct fb_cmap *cmap, int kspc,

int (*getcolreg)(u_int, u_int *, u_int *, u_int *,u_int *, struct fb_info *),

                                struct fb_info *fb_info);

extern int fb_set_cmap(struct fb_cmap *cmap, int kspc,

                              int (*setcolreg)(u_int, u_int, u_int, u_int, u_int,struct fb_info *),

                              struct fb_info *fb_info);

extern struct fb_cmap *fb_default_cmap(int len);

extern void fb_invert_cmaps(void);

2. 通過文件解析

anakinfb.c文件中,cmap如圖


 


 
stifb.c

framebuffer驅(qū)動全篇(四)
    

本文介紹的設備是位于/video目錄下面的anakinfb.c驅(qū)動程序。雖然我不清楚那個設備的特性,但是從對程序的分析中我們?nèi)匀恢廊绾尉帉懸粋€frame buffer設備驅(qū)動。

    本文是個標準的fb驅(qū)動。共221行,包含函數(shù)如下:

 

1.         static int  anakinfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, u_int *transp, struct fb_info *info) 31

2.         static int anakinfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,u_int transp, struct fb_info *info) 45

3.         static int anakinfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info) 57

4.         static int anakinfb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) 75

5.         static int anakinfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) 111

6.         static int anakinfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,     struct fb_info *info) 117

7.         static int anakinfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,     struct fb_info *info) 130

8.         static int anakinfb_switch_con(int con, struct fb_info *info) 147

9.         static int anakinfb_updatevar(int con, struct fb_info *info) 155

10.     static void anakinfb_blank(int blank, struct fb_info *info) 161

11.     int __init anakinfb_init(void) 178


函數(shù)1,2是寄存器操作用。

函數(shù)3,4,56,7fb_ops函數(shù)

函數(shù)8用于切換控制臺

函數(shù)9用于更新變量

函數(shù)10用于閃爍屏幕

函數(shù)11用于初始化設備

    很奇怪,對fb設備的讀寫函數(shù)怎么沒有!值得說明的是open,release,read,write,ioctl,mmap等函數(shù)的實現(xiàn)是由fbmem.c文件實現(xiàn)了。也就是說所有的fb設備在給定了fb_info后,所有的操作都是一樣的。在明確的fb_info前提下,fbmem.c中的函數(shù)可以工作的很好。這樣大家應該感到非常輕松了吧,只要完成上述的幾個設備相關的函數(shù),frame buffer設備的驅(qū)動就寫完了:)

 

系統(tǒng)的結(jié)構(gòu)如圖:

 

Stifb驅(qū)動模型

linux/drivers/video/stifb.c - Generic frame buffer driver for HP * workstations with STI (standard text interface) video firmware.

這個驅(qū)動程序和前面的anakin設備完全不同,因為他不是采用標準的格式,而是根據(jù)based on skeletonfb, which wasCreated 28 Dec 1997 by Geert Uytterhoeven也就是skeletonfb.c提供的框架完成的。

230行,包含函數(shù)如下:

1.         static int sti_encode_fix(struct fb_fix_screeninfo *fix, const void *par, struct fb_info_gen *info) 60

2.         static int sti_decode_var(const struct fb_var_screeninfo *var,void *par, struct fb_info_gen *info) 71

3.         static int sti_encode_var(struct fb_var_screeninfo *var, const void *par, struct fb_info_gen *info) 78

4.         static void sti_get_par(void *par, struct fb_info_gen *info) 94

5.         static void sti_set_par(const void *par, struct fb_info_gen *info) 99

6.         static int sti_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue, unsigned *transp, struct fb_info *info) 104

7.         static int sti_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) 111

8.         static void sti_set_disp(const void *par, struct display *disp, struct fb_info_gen *info) 118

9.         static void sti_detect(void) 127

10.     static int sti_blank(int blank_mode, const struct fb_info *info) 132

11.     int __init stifb_init(void) 161

12.     void stifb_cleanup(struct fb_info *info) 201

13.     int __init stifb_setup(char *options) 208

其中110是必須的,參考下面的圖。

11是初始化代碼

1213沒有完成具體功能

 

再給出fb_fix_screeninfo系統(tǒng)調(diào)用結(jié)構(gòu)圖:

 

Frame bufferconsole

Framebuffer作為顯卡在內(nèi)核中的注冊設備,為了滿足應用需要,通常還要為console操作提供專用操作函數(shù)。

Console是系統(tǒng)提供的一種特殊的文本輸出終端,如圖所示。常用的console已經(jīng)不再是從前的單色顯示,而是16色或者更多顏色顯示。根據(jù)文本的代表的不同屬性,顯示不同的顏色。

把對console的支持內(nèi)嵌到fb的驅(qū)動中,或許有其自己的道理,我沒有看出來。不過既然要提供這種支持,我們的驅(qū)動程序就要添枝加葉了。

 

在準fb設備設備驅(qū)動中是沒有對console支持的。

只有在非標準的fb驅(qū)動,也就是基于skeletonfb.c架構(gòu)的程序,需要提供這部分代碼。

下面從各個方面介紹framebufferconsole的支持。

1.       各個文件中的支持

fb.h文件中

struct fb_info結(jié)構(gòu)中:

struct display *disp;              /* initial display variable */

    struct vc_data *display_fg;           /* Console visible on this display */

int (*changevar)(int);            /* tell console var has changed */

    int (*switch_con)(int, struct fb_info*); /* tell fb to switch consoles */

 

fbgen.c文件中:

void fbgen_set_disp(int con, struct fb_info_gen *info)

int fbgen_update_var(int con, struct fb_info *info)

int fbgen_switch(int con, struct fb_info *info)

 

新增加文件fbcon.c

struct display fb_display[MAX_NR_CONSOLES];

char con2fb_map[MAX_NR_CONSOLES];

…..

 

新增加文件fbcon.h

struct display_switch

struct display

 

新增文件console_struct.h:

struct vc_data

……

 

2.       console中的顏色設定
該部分內(nèi)容準備略掉,可以自行參考
fbcon-cfb*.c文件。

 

3.       consolefb的高層理解

當我們在fb中引入console后,就相當于把一張白紙變成了一個日記本。本來對于fb來說只有顏色和位置的關系,引入console后,首先就是console的描述。
  
每個console相當于日記本的一頁,不同的console可以切換。Console因為是要顯示文本,又和字體聯(lián)系到一起。Console的管理是十分復雜的,遠遠超過了framebuffer本身。在RH9中,我們可以自己體驗一下consolefb的協(xié)調(diào)問題。

使用Init3多用戶模式登陸,這里是沒有X server支持的。所有的輸入輸出都是基于console的。Framebuffer就相當于你的顯示器。通過ALT+CTRL+F*,我們可以切換到不同的console,而每個console的設置都可以很獨立的完成。每隔console會在自己的數(shù)據(jù)區(qū)記錄歷史命令,在不同的console可以登陸不同的用戶到系統(tǒng)。但是,因為只有一個屏幕,所以當前可視的console只有一個。Frame buffer驅(qū)動程序要能夠根據(jù)ALT+CTRL+F*切換命令去完成console的切換顯示。

   這樣大家應該明白frame bufferconsole的關系了吧。后續(xù)我們會具體講述fbconsole的支持。但是對console本身不會設計太多,具體參考ttyconsole的設計。當完成了fbconsole的支持,frame buffer device driver設計就完了:)

framebuffer驅(qū)動全篇(五)
    

Fb console中的字體

/driver/video目錄下:
font_6x11.c,font_8x8.c,font_8x16.c

font_acorn_8x8.c,font_pearl_8x8.c,

font_sun8x16.c,font_sun12x22.c

fonts.c

這些文件都是用來處理在fbcon中的字體顯示問題。其中除最后一個文件fonts.c外,其他都是字模文件由cpi2fnt產(chǎn)生。

/include/video/目錄下:

font.h

1.          首先介紹font.h文件

font.h文件中,定義了字體的描述結(jié)構(gòu)

struct fbcon_font_desc {

    int idx;     /字體的索引號

    char *name;/字體的描述

    int width, height;/字模的寬和高

    void *data;/字模的起始指針

    int pref;    /額外信息,平臺用

};

width的值不一定是8的整數(shù)倍,考慮到計算機存儲的問題,即使width小于8的整數(shù)倍,存儲時仍以字節(jié)為單位,不足的右補齊0

Linux內(nèi)核自帶了7種字體,name依次為:

font_vga_8x8,

                            font_vga_8x16,

                            font_pearl_8x8,

                            font_vga_6x11,

                            font_sun_8x16,

                            font_sun_12x22,

                            font_acorn_8x8;

根據(jù)定義name長度不大于32字節(jié)。

2.          Font.c文件

/* 根據(jù)字體名返回該字體的描述結(jié)構(gòu) */

 struct fbcon_font_desc *fbcon_find_font(char *name);

 

/*根據(jù)屏幕大小,獲取默認字體描述 */

struct fbcon_font_desc *fbcon_get_default_font(int xres, int yres);

 

由此看來,linux中基于fbcon的字體比較單一,描述和使用也相對簡單。主要是由于采用字模描述,只描述256ascii字符,故存儲空間不大,從204811264不等。

Fbcon中的顏色查找表

Fbcon-cfbx表示該console使用的是xbpp顏色描述。顏色數(shù)為2^x。

在此,我們僅以x=8,x=24舉例,使用顏色分別是256色和真彩16M。

/driver/video/fbcon-cfb8.c

/driver/video/fbcon-cfb24.c

/include/video/fbcon-cfb8.h

/include/video/fbcon-cfb24.h

4個文件實現(xiàn)的具體的操作,而fbcon的底層操作,參考前面的fbcon的介紹,不重復了:)

實現(xiàn)fbcon的顏色映射只需完成下面的功能,以fb8為例:

struct display_switch fbcon_cfb8;  

void fbcon_cfb8_setup(struct display *p);

void fbcon_cfb8_bmove(struct display *p, int sy, int sx, int dy, int dx, int height, int width);

void fbcon_cfb8_clear(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width);

void fbcon_cfb8_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx);

void fbcon_cfb8_putcs(struct vc_data *conp, struct display *p, const unsigned short *s, int count, int yy, int xx);

void fbcon_cfb8_revc(struct display *p, int xx, int yy);

void fbcon_cfb8_clear_margins(struct vc_data *conp, struct display *p,int bottom_only);

fbcon_cfb8是系統(tǒng)的實現(xiàn)關鍵,具體解釋參考fbcon介紹。

fbcon_cfb8_setup函數(shù)完成設定display結(jié)構(gòu)中next_line和next_palne的值。

fbcon_cfb8_bmove函數(shù)完成當前坐標的移動。

fbcon_cfb8_clear函數(shù)通過調(diào)用rectfill函數(shù)清屏幕緩沖區(qū)。

fbcon_cfb8_putc函數(shù)向屏幕輸出單字符,字體寬度必須小于等于16。

fbcon_cfb8_putcs函數(shù)向屏幕輸出字符串。

fbcon_cfb8_revc函數(shù)從屏幕輸入單個字符,并回顯到fb上。

fbcon_cfb8_clear_margins函數(shù)和fbcon_cfb8_clear類似,調(diào)用rectfill清除區(qū)域。

其中,fb_writel函數(shù)和fb_readl函數(shù)實現(xiàn)輸入輸出的底層操作。這兩個函數(shù)實際上實在fbcon_h中定義的宏操作,IOMEM操作而已。

關注一下“(nibbletab_cfb8[*cdat++ >> 4] & eorx) ^ bgx,”

這是所謂8bpp的具體實現(xiàn),不同的位深就在寫fb緩沖時體現(xiàn)了。讓我們從后向前分析,

1.()^bgx,顏色和背景色異或,只有這樣才能保證背景色改變時,文字一直顯示。

2.~&eorx,eorx是前景色和背景色異或后的值,只有在前景色和背景色一致的時候,eorx才是0。

3. nibbletab_cfb8[~],根據(jù)字體的~值,調(diào)用查找表,取顏色值

4.~從字體文件中去讀字模的值。

 

還有點疑問,就是這兩句的作用,attr_fgcol在fbcon_h中定義:

fgx=attr_fgcol(p,c);

    bgx=attr_bgcol(p,c);

從前面的看,c應該是個字符的ascii碼,ascii與顏色有什么關系呢?研究中….

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    日韩欧美二区中文字幕| 亚洲中文字幕日韩在线| 少妇淫真视频一区二区| 国产欧美一区二区久久| 国产视频一区二区三区四区| 国产又粗又猛又大爽又黄| 青草草在线视频免费视频| 厕所偷拍一区二区三区视频| 欧美国产日韩变态另类在线看| 成年人免费看国产视频| 好吊色欧美一区二区三区顽频| 成人国产激情在线视频| 国内精品一区二区欧美| 91偷拍裸体一区二区三区| 欧美日韩亚洲精品在线观看| 91精品欧美综合在ⅹ| 天堂网中文字幕在线视频| 一区二区三区欧美高清| 激情五月天深爱丁香婷婷| 国产色偷丝袜麻豆亚洲| 国产精品福利一级久久| 中文字幕乱码亚洲三区| 老司机精品视频在线免费看| 中文字幕人妻一区二区免费| 亚洲a码一区二区三区| 好东西一起分享老鸭窝| 午夜精品在线视频一区| 九九热这里只有免费精品| 日韩精品你懂的在线观看| 69老司机精品视频在线观看| 日韩高清毛片免费观看| 色无极东京热男人的天堂| 国内尹人香蕉综合在线| 国产日产欧美精品视频| 日本最新不卡免费一区二区| 久久99夜色精品噜噜亚洲av| 好吊一区二区三区在线看| 办公室丝袜高跟秘书国产| 日韩一区中文免费视频| 日本高清一道一二三区四五区| 午夜福利视频偷拍91|