FrameBuffer驱动学习

本文深入介绍了Linux系统的帧缓冲(Framebuffer)机制,详细解析了fb_info、fb_ops等关键数据结构的功能与作用,以及如何注册与注销帧缓冲设备。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


FrameBuffer驱动学习

Daniel Wood 20110301
转载时请注明出处和作者
文章出处:http://danielwood.cublog.cn
作者:Daniel Wood
------------------------------------------------------------
写在前面的话:
这篇文章是自己学习Framebuffer所用,其实里面的东西狠水狠基本的,很多都是从他人的文章中Ctrl+C过来的,如果你没有太多的时间,还是直接跳过了,免得耽误了你的青春,污了你的双眸。

Framebuffer翻译过来是帧缓冲,是Linux系统为显示设备提供的一个接口,它将显示缓冲区抽象,屏蔽图像硬件的底层差异,允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。用户不必关心物理显示缓冲区的具体位置及存放方式,这些都由帧缓冲设备驱动本身来完成。对于帧缓冲设备而言,只要在显示缓冲区中与显示点对应的区域写入颜色值,对应的颜色会自动在屏幕上显示。

帧缓冲设备是标准的字符设备,主设备号为29,对应于/dev/fb(/dev/fb1,/dev/fb2…)设备文件。

注:代码版本2.6.35.6

帧缓冲数据结构

fb_info结构体

fb.h [include\linux]

struct fb_info {
    int node;
    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
    /* assigned backlight device */
    /* set before framebuffer registration, 
     remove after unregister */

    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 */
    /* From here on everything is device dependent */
    void *par;
    /* we need the PCI or similiar aperture base/size not
     smem_start/size as smem_start may just be an object
     allocated inside the aperture so may not actually overlap */

    struct apertures_struct {
        unsigned int count;
        struct aperture {
            resource_size_t base;
            resource_size_t size;
        } ranges[0];
    } *apertures;
};

fb_info是Linux为帧缓冲设备定义的驱动层接口。它不仅包含了设备的设置参数,状态以及操作函数。每个帧缓冲设备都与一个fb_info结构相对应。

其中node成员域标示了特定的FrameBuffer,实际上也就是一个FrameBuffer设备的次设备号。fb_var_screeninfo结构体成员记录用户可修改的显示控制器参数,包括屏幕分辨率和每个像素点的比特数。fb_fix_screeninfo中记录用户不能修改的显示控制器的参数,如屏幕缓冲区的物理地址,长度。

fb_ops结构体

fb.h [include\linux]

struct fb_ops {
    /* open/release and usage marking */
    struct module *owner;
    int (*fb_open)(struct fb_info *info, int user);
    int (*fb_release)(struct fb_info *info, int user);
    /* For framebuffers with strange non linear layouts or that do not
     * work with normal memory mapped access
     */

    ssize_t (*fb_read)(struct fb_info *info, char __user *buf,
             size_t count, loff_t *ppos);
    ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,
             size_t count, loff_t *ppos);
    /* checks var and eventually tweaks it to something supported,
     * DO NOT MODIFY PAR */

    int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);
    /* set the video mode according to info->var */
    int (*fb_set_par)(struct fb_info *info);
    /* set color register */
    int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
             unsigned blue, unsigned transp, struct fb_info *info);
    /* set color registers in batch */
    int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);
    /* blank display */
    int (*fb_blank)(int blank, struct fb_info *info);
    /* pan display */
    int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info*info);
    /* Draws a rectangle */
    void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect*rect);
    /* Copy data from area to another */
    void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea*region);
    /* Draws a image to the display */
    void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);
    /* Draws cursor */
    int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);
    /* Rotates the display */
    void (*fb_rotate)(struct fb_info *info, int angle);
    /* wait for blit idle, optional */
    int (*fb_sync)(struct fb_info *info);
    /* perform fb specific ioctl (optional) */
    int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
            unsigned long arg);
    /* Handle 32bit compat ioctl (optional) */
    int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
            unsigned long arg);
    /* perform fb specific mmap */
    int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
    /* get capability given var */
    void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
             struct fb_var_screeninfo *var);
    /* teardown any resources to do with this framebuffer */
    void (*fb_destroy)(struct fb_info *info);
};

它是提供给底层设备驱动的一个接口。通常我们编写字符驱动的时候,要填写一个file_operations结构体,并使用register_chrdev()注册之,以告诉Linux如何操控驱动。当我们编写一个FrameBuffer的时候,就要依照Linux FrameBuffer编程的套路,填写fb_ops结构体。这个fb_ops也就相当于通常的file_operations结构体。

fb_var_screeninfo结构体

struct fb_var_screeninfo {
    __u32 xres;            /* visible resolution        */
    __u32 yres;
    __u32 xres_virtual;        /* virtual resolution        */
    __u32 yres_virtual;
    __u32 xoffset;            /* offset from virtual to visible */
    __u32 yoffset;            /* resolution            */
    __u32 bits_per_pixel;        /* guess what            */
    __u32 grayscale;        /* != 0 Graylevels instead of colors */
    struct fb_bitfield red;        /* bitfield in fb mem if true color, */
    struct fb_bitfield green;    /* else only length is significant */
    struct fb_bitfield blue;
    struct fb_bitfield transp;    /* transparency            */    
    __u32 nonstd;            /* != 0 Non standard pixel format */
    __u32 activate;            /* see FB_ACTIVATE_*        */
    __u32 height;            /* height of picture in mm */
    __u32 width;            /* width of picture in mm */
    __u32 accel_flags;        /* (OBSOLETE) see fb_info.flags */
    /* Timing: All values in pixclocks, except pixclock (of course) */
    __u32 pixclock;            /* pixel clock in ps (pico seconds) */
    __u32 left_margin;        /* time from sync to picture    */
    __u32 right_margin;        /* time from picture to sync    */
    __u32 upper_margin;        /* time from sync to picture    */
    __u32 lower_margin;
    __u32 hsync_len;        /* length of horizontal sync    */
    __u32 vsync_len;        /* length of vertical sync    */
    __u32 sync;            /* see FB_SYNC_*        */
    __u32 vmode;            /* see FB_VMODE_*        */
    __u32 rotate;            /* angle we rotate counter clockwise */
    __u32 reserved[5];        /* Reserved for future compatibility */
};

fb_var_screeninfo结构体成员记录用户可修改的显示控制器参数,包括屏幕分辨率和每个像素点的比特数。fb_var_screeninfo中的xres定义屏幕一行有多少个点, yres定义屏幕一列有多少个点, bits_per_pixel定义每个点用多少个字节表示。

fb_fix_screeninfo结构体


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 */
    unsigned long mmio_start;    /* Start of Memory Mapped I/O */
                    /* (physical address) */
    __u32 mmio_len;            /* Length of Memory Mapped I/O */
    __u32 accel;            /* Indicate to driver which    */
                    /* specific chip/card we have    */
    __u16 reserved[3];        /* Reserved for future compatibility */
};

fb_fix_screeninfo中记录用户不能修改的显示控制器的参数,如屏幕缓冲区的物理地址,长度。当对帧缓冲设备进行映射操作的时候,就是从fb_fix_screeninfo中取得缓冲区物理地址的。上述数据成员都需要在驱动程序中初始化和设置。

其他的结构体都可以在fb.h [include\linux]中找到。

注册与注销帧缓冲设备

定义在fb.h [include\linux]

extern int register_framebuffer(struct fb_info *fb_info);
extern int unregister_framebuffer(struct fb_info *fb_info);

实现在fbmem.c [drivers\video]

代码略。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值