浅析Frambuffer

   linux内核中Frambuffer代表的就是一个虚拟的显示设备,其目的是达到一种分层的思想,即抽象出来的显示设备对上面各个调用模块来说是统一不变的。对于不同设备对应一个个fb_info结构,最终操作的还是fb_info.fbops,底层设备与Frambuffer层建立连接是通过register_framebuffer(struct fb_info *fb_info)函数来建立连接的,最直接的代码如下:

int register_framebuffer(struct fb_info *fb_info)
{
             .
             .
             .
 for (i = 0 ; i < FB_MAX; i++)     //找到一个空的位置用于存放新的fb_info
		if (!registered_fb[i])//该数组在fbmem中定义,作为全局变量使用
			break;
	fb_info->node = i;

fb_info->dev = device_create(fb_class, fb_info->device, MKDEV(FB_MAJOR, i), "fb%d", i);//创建一个B_MAJOR为主设备号,i为次设备号,名称为fbi的设备节点
         ........对bf_info 进行进一步配置.......
	registered_fb[i] = fb_info;//将fb_info放入到数组中去
        。。。。。。
        return 0;
}
现在假设一个应用程序来打开上面刚刚建立的设备节点,通过主设备号找到file_operations,然后调用其中的open成员函数,即fb_open()函数:

static int fb_open(struct inode *inode, struct file *file)
{
	int fbidx = iminor(inode);
	struct fb_info *info;
	int res = 0;

	if (fbidx >= FB_MAX)
		return -ENODEV;
#ifdef CONFIG_KMOD
	if (!(info = registered_fb[fbidx]))
		try_to_load(fbidx);
#endif /* CONFIG_KMOD */
	if (!(info = registered_fb[fbidx]))
		return -ENODEV;
	if (!try_module_get(info->fbops->owner))
		return -ENODEV;
	file->private_data = info;
	if (info->fbops->fb_open) {
		res = info->fbops->fb_open(info,1);
		if (res)
			module_put(info->fbops->owner);
	}
	return res;
}
可见是通过次设备号找到上面注册的fb_info,并调用fb_info.fbops中的fb_open()成员函数,其他read,write,ioctl等最终调用的也是fb_info.fbops中对应的成员函数,这样就保证了frambuffer对上层调用的稳定性。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值