帧缓冲(frame buffer)读书笔记
由于处理器带显示器的硬件连接方式与变化,所以对于显示驱动来说,要能支持这些不同硬件的连接方式,并把这些差别屏蔽在内部,使得用户感受不到这些不同,带给用户统一的体验。
fb(frame buffer)对应了显示输出设备,把显示设备抽象为了显示的内容。
我们先看fbmem.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
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, }; |
对于直接对应驱动的框架我们先看他的open操作就可以很快的明确其框架管理的实体是什么。我们先来分析fb_open函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
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; info = get_fb_info(fbidx); //根据ID获取fb_info结构体 if (!info) { request_module("fb%d", fbidx); info = get_fb_info(fbidx); if (!info) return -ENODEV; } if (IS_ERR(info)) return PTR_ERR(info); mutex_lock(&info->lock); //FLAG if (!try_module_get(info->fbops->owner)) { res = -ENODEV; goto out; } file->private_data = info; //把fb_info加入到私有数据(相当于实例化) if (info->fbops->fb_open) { res = info->fbops->fb_open(info,1); if (res) module_put(info->fbops->owner); } #ifdef CONFIG_FB_DEFERRED_IO if (info->fbdefio) fb_deferred_io_open(info, inode, file); #endif out: mutex_unlock(&info->lock); //ENDFLAG if (res) put_fb_info(info); return res; } |
以上处理核心是根据ID获取了fb_info后加入到了file->private_data。接着我们来分析下fb_info
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
struct fb_info { 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; /* 显示相关的可变信息 */ struct fb_fix_screeninfo 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; /* 支持的显示模式列表 */ struct fb_videomode *mode; /* 当前的显示模式*/ ................. 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 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 */ }; |
这里最重要的三个属性是 var、fix、fbops