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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天未及海宽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值