一. framebuffer结构体
1. fb_info
struct fb_info {
int node; //次设备号
int flags;
struct mutex lock;
struct mutex mm_lock;
struct fb_var_screeninfo var; //可变参数
struct fb_fix_screeninfo fix; //不可变参数
struct fb_monspecs monspecs;
struct work_struct queue;
struct fb_pixmap pixmap;
struct fb_pixmap sprite;
struct fb_cmap cmap;
struct list_head modelist;
struct fb_videomode *mode; //显示模式
#ifdef CONFIG_FB_BACKLIGHT
struct backlight_device *bl_dev;//背光设备
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; //设备文件
struct device *dev; //设备文件
int class_flag;
#ifdef CONFIG_FB_TILEBLITTING
struct fb_tile_ops *tileops;
#endif
char __iomem *screen_base; //虚拟基地址
unsigned long screen_size; //虚拟显存大小
void *pseudo_palette; //调色板 一般设置为PALETTE_BUFF_CLEAR
#define FBINFO_STATE_RUNNING 0
#define FBINFO_STATE_SUSPENDED 1
u32 state; //状态 状态值为上面两个宏
void *fbcon_par;
void *par;
struct apertures_struct {
unsigned int count;
struct aperture {
resource_size_t base;
resource_size_t size;
} ranges[0];
} *apertures;
};
2. fb_var_screeninfo
struct fb_var_screeninfo {
__u32 xres; //水平分辨率
__u32 yres; //垂直分辨率
__u32 xres_virtual; //水平虚拟分辨率
__u32 yres_virtual; //存执虚拟分辨率
__u32 xoffset;//水平可视区域的偏移
__u32 yoffset;//垂直可视区域的偏移
__u32 bits_per_pixel; //每像素占用多少bit
__u32 grayscale; //灰度等级
struct fb_bitfield red; //红色位域 offset=11 length=5 (RGB565)
struct fb_bitfield green; //绿色位域 offset=5 length=6
struct fb_bitfield blue; //蓝色位域 offset=0 length=5
struct fb_bitfield transp; //透明度位域
__u32 nonstd; //非标准标志
__u32 activate; //激活标志
__u32 height; //物理高度
__u32 width; //物理宽度
__u32 accel_flags;//硬件加速标志
__u32 pixclock;
__u32 left_margin; //左边缘宽度
__u32 right_margin; //右边缘宽度
__u32 upper_margin; //上边缘宽度
__u32 lower_margin; //下边缘宽度
__u32 hsync_len; //水平同步长度
__u32 vsync_len; //垂直同步长度
__u32 sync;
__u32 vmode;
__u32 rotate;//旋转
__u32 reserved[5];
};
2.1 位域 fb_bitfield
struct fb_bitfield {
__u32 offset; //偏移量
__u32 length; //长度
__u32 msb_right; //高位有效?对齐方式
};
3.fb_fix_screeninfo
struct fb_fix_screeninfo {
char id[16];
unsigned long smem_start; //物理显存起始地址
__u32 smem_len; //显示长度(xres*yres*bits_per_pixel/8)
__u32 type; //显示类型(FB_TYPE_PACKED_PIXELS)
__u32 type_aux;
__u32 visual; //颜色模式(FB_VISUAL_TRUECOLOR)
__u16 xpanstep;
__u16 ypanstep;
__u16 ywrapstep;
__u32 line_length; //一行像素的字节数(xres*bits_per_pixel/8)
unsigned long mmio_start;
__u32 mmio_len;
__u32 accel;//加速类型
__u16 reserved[3];
};
4. 操作函数集
struct fb_ops {
struct module *owner;
int (*fb_open)(struct fb_info *info, int user); //打开
int (*fb_release)(struct fb_info *info, int user); //释放
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); //写
int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info); //检测参数
int (*fb_set_par)(struct fb_info *info); //设置参数
int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,unsigned blue, unsigned transp, struct fb_info *info); //设置调色板
int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);
int (*fb_blank)(int blank, struct fb_info *info); //清屏
int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info); //
void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect); //填充区域
void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region); //复制区域
void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image); //图形填充
int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor); //绘制光标
void (*fb_rotate)(struct fb_info *info, int angle); //旋转屏幕
int (*fb_sync)(struct fb_info *info); //同步 等待blit空闲
int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,unsigned long arg); //控制
int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,unsigned long arg); //32位兼容控制
int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma); //映射
void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,struct fb_var_screeninfo *var);
void (*fb_destroy)(struct fb_info *info); //销毁
int (*fb_debug_enter)(struct fb_info *info);
int (*fb_debug_leave)(struct fb_info *info);
};
二. fb系统初始化
1. 主设备号
#define FB_MAJOR 29
2. fbmem_init
static int __init fbmem_init(void)
{
proc_create("fb", 0, NULL, &fb_proc_fops); //创建"/proc/fb"文件
if (register_chrdev(FB_MAJOR,"fb",&fb_fops)) //注册所有的fb字符设备,并捆绑fb_fops操作函数集合
printk("unable to get major %d for fb devs\n", FB_MAJOR);
fb_class = class_create(THIS_MODULE, "graphics"); //创建"/sys/class/graphics"
if (IS_ERR(fb_class)) {
printk(KERN_WARNING "Unable to create fb class; errno = %ld\n", PTR_ERR(fb_class));
fb_class = NULL;
}
return 0;
}
3. /proc下的接口fb_proc_fops
3.1 操作函数集
static const struct file_operations fb_proc_fops = {
.owner = THIS_MODULE,
.open = proc_fb_open, //打开
.read = seq_read, //读取
.llseek = seq_lseek, //读写指针
.release = seq_release,
};
3.2 cat /prco/fb
cat /proc/fb
0 ti81xxfb
1 ti81xxfb
2 ti81xxfb
先调用open方法
static int proc_fb_open(struct inode *inode, struct file *file)
{
return seq_open(file, &proc_fb_seq_ops); //主要做了file->private_data->op=proc_fb_seq_ops
}
proc_fb_seq_ops
static const struct seq_operations proc_fb_seq_ops = {
.start = fb_seq_start, //读写位置开头
.next = fb_seq_next, //下一个读写位置
.stop = fb_seq_stop, //无操作
.show = fb_seq_show, //显示
};
fb_seq_show函数
static int fb_seq_show(struct seq_file *m, void *v)
{
int i = *(loff_t *)v;
struct fb_info *fi = registered_fb[i]; //获取fb_info结构体
if (fi)
seq_printf(m, "%d %s\n", fi->node, fi->fix.id); //打印其设备编号及设备信息到seq_file文件
return 0;
}
接着调用read方法
seq_read方法调用proc_fb_seq_ops的各个方法,最终将seq_file文件里的打印信息,复制到用户空间的buf里面
4. 字符设备捆绑的fb_fops
4.1 操作函数集
static const struct file_operations fb_fops = {
.owner = THIS_MODULE, //模块所有者
.read = fb_read, //读
.write = fb_write, //写
.unlocked_ioctl = fb_ioctl, //控制
#ifdef CONFIG_COMPAT
.compat_ioctl = fb_compat_ioctl,
#endif
.mmap = fb_mmap, //映射
.open = fb_open, //打开
.release = fb_release, //是否
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
.get_unmapped_area = get_fb_unmapped_area,
#endif
#ifdef CONFIG_FB_DEFERRED_IO
.fsync = fb_deferred_io_fsync,
#endif
.llseek = default_llseek, //读写指针
};
4.1.1 打开
static int fb_open(struct inode *inode, struct file *file)
__acquires(&info->lock)
__releases(&info->lock)
{
int fbidx = iminor(inode); //根据节点算出次设备号
struct fb_info *info;
int res = 0;
if (fbidx >= FB_MAX)
return -ENODEV;
info = registered_fb[fbidx]; //从全局registered_fb数组中获取fb_info
if (!info)
request_module("fb%d", fbidx);
info = registered_fb[fbidx];
if (!info)
return -ENODEV;
mutex_lock(&info->lock);
if (!try_module_get(info->fbops->owner)) {
res = -ENODEV;
goto out;
}
file->private_data = info; //将fb_info数据存放在文件的私有数据里
if (info->fbops->fb_open) { //若fb_info的fb操作函数集有实现open方法
res = info->fbops->fb_open(info,1); //则调用其open方法
if (res)
module_put(info->fbops->owner);
}
#ifdef CONFIG_FB_DEFERRED_IO
if (info->fbdefio)
fb_deferred_io_open(info, inode, file);
#endif
out:
mute