概述
一:framebuffer?
帧缓冲(一屏幕数据)(简称fb),内核中虚拟出的设备,向应用层提供一个统一标准的显示接口(frambuffer)。
容许应用层在图形模式下直接对显示缓冲区进行读写操作。
framebuffer用来操作物理显存的位置,换页机制等操作。
使用framebuffer时,linux将显卡置于图形模式下。
framebuffer的设备文件: /dev/fb0。
1:对应的源文件:linux/driver/video/总抽象设备:fbcon.c(还有与各种显卡驱动相关的源文件)
设备驱动的源文件:linux/driver/video/fbmem.c linux/include/linux/fb.h(framebuffer的设备信息的头文件)(主要用来分析这两个文件)
linux/drivers/video/fbgen.c或者linux/drivers/video目录下的其它设备驱动是比较好的参考资料。
分析结构体:
1:fb_info:
struct fb_info { //用来描述一个fb设备的结构体
atomic_t count;
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 */ //fb的可变参数跟屏幕输出有关系
struct fb_fix_screeninfo fix; /* Current fix */ //fb的固定参数
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; //对应的fb的操作函数
struct device *device; /* This is the parent */ //fb的父设备
struct device *dev; /* This is this fb device */ //fb的当前设备
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 */ //16位调色板
#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 similar 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;
bool skip_vt_switch; /* no VT switch on suspend/resume required */
};
2;fb_var_screeninfo (fb的可变参数)
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 = color, 1 = grayscale, */
/* >1 = FOURCC */
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 */ //物理高度mm
__u32 width; /* width of picture in mm */ //物理宽度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) */ //像素时钟
//lcd时序参数
__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 colorspace; /* colorspace for FOURCC-based modes */
__u32 reserved[4]; /* Reserved for future compatibility */
};
3:fb_fix_screeninfo //fb的固定参数:显卡属性,运行时不能被修改
struct fb_fix_screeninfo {
char id[16]; /* identification string eg "TT Builtin" */ID
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 */内存映射的I/O起始
/* (physical address) */
__u32 mmio_len; /* Length of Memory Mapped I/O */ I/O的大小
__u32 accel; /* Type of acceleration available */ 可用的加速类型
__u16 reserved[3]; /* Reserved for future compatibility */
};
4:fb_cmap:描述设备无关的映射信息,可以通过FBIOGETCMAP 和 FBIOPUTCMAP对应的ioctl操作设置获取颜色映射信息.
struct fb_cmap {
__u32 start; /* First entry */ 第一个入口
__u32 len; /* Number of entries */ 入口的数字
__u16 *red; /* Red values */ 红
__u16 *green;
__u16 *blue;
__u16 *transp; /* transparency, can be NULL */ 透明,可以为零
};
5:struct fb_ops
用户应用可以使用ioctl()系统调用来操作设备,这个结构就是用一支持ioctl()的这些操作的。
struct fb_ops {
/*打开释放有用的标志 */
struct module *owner;
int (*fb_open)(struct fb_info *info, int user);
int (*fb_release)(struct fb_info *info, int user);
/* 得到固定参数*/
int (*fb_get_fix)(struct fb_fix_screeninfo *fix, int con,struct fb_info *info);
/* 设置颜色寄存器 */
int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,unsigned blue, unsigned transp, struct fb_info *info);
/* 得到改变参数 */
int (*fb_get_var)(struct fb_var_screeninfo *var, int con,struct fb_info *info);
/* 设置改变参数 */
int (*fb_set_var)(struct fb_var_screeninfo *var, int con,struct fb_info *info);
/* 批量设置颜色寄存器*/
int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);
/*得到色彩表 */
int (*fb_get_cmap)(struct fb_cmap *cmap, int kspc, int con,struct fb_info *info);
/*绘制一个矩形 */ //cfbfillrect.c
void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
/* 拷贝数据从一个区域到另一个区域 */ //cfbcopyarea.c文件中(可编译成.ko文件)
void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
/*将图像绘制到显示器 */ //cfbimgblt.c
void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);
/* 设置*/
int (*fb_set_cmap)(struct fb_cmap *cmap, int kspc, int con,struct fb_info *info);
/* 平移显示 */
int (*fb_pan_display)(struct fb_var_screeninfo *var, int con,struct fb_info *info);
/*执行特定的ioctl*/
int (*fb_ioctl)(struct inode *inode, struct file *file, unsigned int cmd,unsigned long arg, int con, struct fb_info *info);
/* 执行fb特定的mmap */
int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
/* 切换到光栅图像模式*/
int (*fb_rasterimg)(struct fb_info *info, int start); };
二:fbmem.c
处于设备驱动的中心位置,它为上层的应用提供调用,也为下层的驱动提供接口,哪些硬件的驱动需要到这的接口来想体统注册,fbmem.c为所有的framebuffer提供了通用的接口
1:文件的全局变量
struct fb_info *registered_fb[FB_MAX] __read_mostly; //所注册的所有fb_info都保存在该数组中
int num_registered_fb __read_mostly; //添加一个结构体,该参数自动+1;
static struct {
const char *name;
int (*init)(void);
int (*setup)(void);
} fb_drivers[] __initdata= { ....}; //如果静态连接到内核,对应添加到该表中,动态insmod。则不需要关心。
framebuffer_alloc用来分配一个fb_info 结构体。
register_framebuffer(struct fb_info *fb_info); unregister_framebuffer(struct fb_info *fb_info);
是提供设备驱动的接口,几乎所有的底层设备驱动所要做的事就是填充fb_info,用来注册/注销自己,
注意分层的概念:设备驱动向用户程序提供调用接口,我们实现底层硬件操作定义file_operations结构体想系统提供调用接口。
static struct fb_info *file_fb_info(struct file *file):我们采用该函数来找到对应的注册的fb_info结构体
其中fb_info中的struct fb_ops *fbops;是底层操作函数:file_operations:是上层系统调用接口,可直接调用,
当ioctl系统调用时,最终调用到接口到的fb_ops中的函数中,去支持这些操作。
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()操作来操作硬件。
fb_set_var()是最重要的,它用于设定显示卡的模式和其它属性,下面是函数fb_set_var()的执行步骤:
1)检测是否必须设定模式
2)设定模式
3)设定颜色映射
4) 根据以前的设定重新设置LCD控制器的各寄存器。
其中比较重要的步奏是设置底层的fb_ops操作函数。
最后
以上就是欣喜紫菜为你收集整理的linux--framebuffer驱动框架的全部内容,希望文章能够帮你解决linux--framebuffer驱动框架所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复