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