了解framebuffer driver,skeletonfb.c有著一個framebuffer基本的架構,值得參考。筆記如下:

顯卡可支援多螢幕,因此可能有多個display。而每個display可有自己的data,因此每個display都是一個framebuffer device,意即各有其fb_info。fb_info中的par是硬體相關的state,硬體只有一份,因此這些state對每個display來說是共享的。任一個display做了改變 (如resolution,var->xres和var->yres),其他的display都可得知此狀況。以下是framebuffer driver需要或不需要實作的function:

int xxxfb_init(void):

    在linux kernel 2.6後引入platform的概念,讓driver更加容易實作。這個function的功能是向platform註冊這支driver,即執行platform_driver_register()。如int __init   s3c2410fb_init(void)

static int xxxfb_open(struct fb_info *info, int user) / static int xxxfb_release(struct fb_info *info, int user):

    Optional。在framebuffer device open/close時執行,通常不需實作。

static int xxxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info):

    Optional。檢查硬體是否支援傳入的struct var所指定的狀態。這個function並不改變hardware state,意即fb_info和par不變。值的部份,會做round up。爆掉的話就發-EINVAL。此處是driver註冊後,調整var的唯一地方。意即在其他的function改變var的內容是錯的。

static int xxxfb_set_par(struct fb_info *info):

    Optional。利用fb_info裡的fb_var_screeninfo,可改變frmebuffer的resolution,pclk等hardware status。此 function將改變par和fb_fix_screeninfo。var是不變的,而是利用其狀態來做硬體設定。在呼叫xxxfb_set_par前應呼叫xxxfb_check_var以確保參數正確。如果resolution不能改,那這個function就不需實作。然而,還是可以透過這個function來讓硬體回到working state,也是一種recover的機制。

static int xxxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)

    Not required。主要是平移的功能。不是很確定,但看起來像vitual resolution。virtual大於visible,因此就有xoffset和yoffset。根據傳入的var裡所指定的xoffset和yoffset來決定display要平移多少。

static int xxxfb_blank(int blank_mode, struct fb_info *info):

    Not required。清空display。

/* ------------ Accelerated Functions --------------------- */

以下為加速的function,會depend on硬體有無此功能。不然則使用generic unaccelerated function。

void xxxfb_fillrect(struct fb_info *p, const struct fb_fillrect *region):

    在screent上畫一矩形。

void xxxfb_copyarea(struct fb_info *p, const struct fb_copyarea *area):

    Required。copy矩形從一個區域到另一個。

void xxxfb_imageblit(struct fb_info *p, const struct fb_image *image):

    Required。複製image,從memory到screen。

int xxxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)"

    Optional。如果有hardware cursor,就不需要。

void xxxfb_rotate(struct fb_info *info, int angle):

    Not required。如果硬體提供此功能,可在此hook。

int xxxfb_sync(struct fb_info *info):

    Not required。使用硬體加速,可能需要sync。

 

    /*
     *  Frame buffer operations
     */

static struct fb_ops xxxfb_ops = {
    .owner        = THIS_MODULE,
    .fb_open    = xxxfb_open,
    .fb_read    = xxxfb_read,
    .fb_write    = xxxfb_write,
    .fb_release    = xxxfb_release,
    .fb_check_var    = xxxfb_check_var,
    .fb_set_par    = xxxfb_set_par,
    .fb_setcolreg    = xxxfb_setcolreg,
    .fb_blank    = xxxfb_blank,
    .fb_pan_display    = xxxfb_pan_display,
    .fb_fillrect    = xxxfb_fillrect,     /* Needed !!! */
    .fb_copyarea    = xxxfb_copyarea,    /* Needed !!! */
    .fb_imageblit    = xxxfb_imageblit,    /* Needed !!! */
    .fb_cursor    = xxxfb_cursor,        /* Optional !!! */
    .fb_rotate    = xxxfb_rotate,
    .fb_sync    = xxxfb_sync,
    .fb_ioctl    = xxxfb_ioctl,
    .fb_mmap    = xxxfb_mmap,
};

static int __devinit xxxfb_probe(struct pci_dev *dev, const struct pci_device_id *ent):

    這是主要的功能了,包括:

        設定fb_info,其中包括註冊所需要的fb_ops

        設定fb_var_screeninfo,這是console要用的

        向系統要求memory address space: request_mem_region()

        最後,register_framebuffer():向fbmem.c層註冊。

kezeodsnx 發表在 痞客邦 PIXNET 留言(0) 人氣()