我是靠谱客的博主 幸福哑铃,最近开发中收集的这篇文章主要介绍linux之framebuffer(2),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1. struct fb_info结构体

struct fb_info {
atomic_t count;
int node;
/* 标记所在的数组标号,最大FB_MAX */
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;	/* 帧缓存事件队列 */
struct fb_pixmap pixmap;	/* 图像硬件mapper */
struct fb_pixmap sprite;	/* 光标硬件mapper */
struct fb_cmap cmap;
/* Current cmap */
struct list_head modelist;
/* 模式列表 */
struct fb_videomode *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
struct fb_ops *fbops;
/* fb设备操作回调 */
struct device *device;
/* 父对象 */
struct device *dev;
/* 表fb设备 */
int class_flag;
/* private sysfs flags */
#ifdef CONFIG_FB_TILEBLITTING
struct fb_tile_ops *tileops;
/* Tile Blitting */
#endif
char __iomem *screen_base;	/* 虚拟地址 */
unsigned long screen_size;	/* ioremap VRAM的数量或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;
#ifdef CONFIG_FB_DEFERRED_IO
struct delayed_work deferred_work;
struct fb_deferred_io *fbdefio;
#endif
};

 

在 drivers/video/fbmem.c中存在一个函数 register_framebuffer(struct fb_info *fb_info);用于向内核注册 fb_info结构体; 在fbmem.c中存在一个全局 struct fb_info指针数组;用于存储注册的fb_info;

static DEFINE_MUTEX(registration_lock);
struct fb_info *registered_fb[FB_MAX] __read_mostly;

2. 调用 register_framebuffer 注册fb_info

在drivers/video/xxxfb.c中 xxx_probe(struct platform_device *dev) 函数中,当设备与驱动匹配成功时调用,如hitfb.c中

static int __devinit hitfb_probe(struct platform_device *dev)
{
struct fb_info *info;
//分配内存
info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
//根据具体填充
info->fbops = &hitfb_ops;
info->var = hitfb_var;
info->fix = hitfb_fix;
info->pseudo_palette = info->par;
info->screen_base = (void *)hitfb_fix.smem_start;
//注册fb_info
ret = register_framebuffer(info);
return 0;
}

register_framebuffer 又调用 do_register_framebuffer 函数;

 do_register_framebuffer源码如下:

int do_register_framebuffer(struct fb_info *fb_info)
{
int i;
struct fb_event event;
struct fb_videomode mode;
//标记注册fb的数量
if (num_registered_fb == FB_MAX)
return -ENXIO;
num_registered_fb++;
//检查为空的数组,然后将所在位置赋给node;
for (i = 0 ; i < FB_MAX; i++)
if (!registered_fb[i])
break;
fb_info->node = i;
//初始化计数,锁
atomic_set(&fb_info->count,1);
mutex_init(&fb_info->lock);
mutex_init(&fb_info->mm_lock);
//fb_info->dev为当前fb设备,fb_info->device为父对象,fb_class在fbmem_init中已经创建,
//且通过register_chrdev向内核注册了,那么该函数调用后就会在/dev下创建设备节点;
//若有多个注册,那么会根据i值增加,如fb0,fb1等;
fb_info->dev = device_create(fb_class,fb_info->device,MKDEV(FB_MAJOR,i),NULL,"fb%d",i);
//初始化 fb_info->dev
fb_init_device(fb_info);
//填充fb_info->pixmap
if (fb_info->pixmap.addr == NULL) {
//addr:指向的内存
若为空,分配
fb_info->pixmap.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL);
if (fb_info->pixmap.addr) {
fb_info->pixmap.size = FBPIXMAPSIZE;//缓冲区大小(byte)
fb_info->pixmap.buf_align = 1;//每个位图的字节对齐
fb_info->pixmap.scan_align = 1;//每个扫描线对齐
fb_info->pixmap.access_align = 32;//每个读或写对齐(bits);
fb_info->pixmap.flags = FB_PIXMAP_DEFAULT;//标志
}
}
fb_info->pixmap.offset = 0;//当前在缓冲区的偏移量
if (!fb_info->pixmap.blit_x) //支持的位块尺寸
fb_info->pixmap.blit_x = ~(u32)0;
if (!fb_info->pixmap.blit_y)
fb_info->pixmap.blit_y = ~(u32)0;
//若模式链表前后其中之一为空,初始化
if (!fb_info->modelist.prev || !fb_info->modelist.next)
INIT_LIST_HEAD(&fb_info->modelist);
//通过fb可变信息内容填充mode,如消隐区,前后上下margin,行/垂直同步长度等;
fb_var_to_videomode(&mode, &fb_info->var);
//若modelist中没有,则将mode通过modelist连接起来
fb_add_videomode(&mode, &fb_info->modelist);
//赋值给全局指针数组
registered_fb[i] = fb_info;
//向客户端通知fb_info注册事件
event.info = fb_info;
fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
return 0;
}

最后

以上就是幸福哑铃为你收集整理的linux之framebuffer(2)的全部内容,希望文章能够帮你解决linux之framebuffer(2)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部