framebuffer 子系统分析

本文深入剖析Linux Framebuffer子系统,包括关键结构体fb_info、fb_var_screeninfo和fb_fix_screeninfo的分析,以及fb_ops接口和背光控制设备的注册流程。同时探讨了开机logo的显示过程和技术细节。
摘要由CSDN通过智能技术生成

一、常见结构体分析

1、fb_info

struct fb_info {
	int node;
	int flags;
	struct mutex lock;		/* 调用open/release/ioctl时的锁 */
	struct mutex mm_lock;		/* fb_mmap和smem_*的锁 */
	struct fb_var_screeninfo var;	/* 当前LCD的可变参数 */
	struct fb_fix_screeninfo fix;	/* 当前LCD的固定参数 */
	struct fb_monspecs monspecs;	/* 当前LCD标准 */
	struct work_struct queue;	/* 帧缓冲工作队列 */
	struct fb_pixmap pixmap;	/* 图像硬件mapper */
	struct fb_pixmap sprite;	/* 光标硬件mapper */
	struct fb_cmap cmap;		/* 当前LCD的颜色表 */
	struct list_head modelist;      /* mode list */
	struct fb_videomode *mode;	/* 当前的video模式 */

#ifdef CONFIG_FB_BACKLIGHT
	/* 对应的背光设备,在framebuffer之前注册及其之后注销 */
	struct backlight_device *bl_dev;

	/* 背光等级调整 */
	struct mutex bl_curve_mutex;	
	u8 bl_curve[FB_BACKLIGHT_LEVELS];
#endif
#ifdef CONFIG_FB_DEFERRED_IO
	struct delayed_work deferred_work;
	struct fb_deferred_io *fbdefio;
#endif

	struct fb_ops *fbops;           /* 帧缓冲底层操作函数接口 */
	struct device *device;		/* 父设备 */
	struct device *dev;		/* fb设备*/
	int class_flag;                    /* 私有sysfs标志 */
#ifdef CONFIG_FB_TILEBLITTING
	struct fb_tile_ops *tileops;    /* Tile Blitting */
#endif
	char __iomem *screen_base;	/* 虚拟基地址即framebuffer起始虚拟地址 */
	unsigned long screen_size;	/* 显存大小 */ 
	void *pseudo_palette;		/* 伪16色颜色表 */ 
#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 */
	/* 私有数据 */
	void *par;
	/* we need the PCI or similiar 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;
};
帧缓冲设备中最关键的数据结构就是fb_info,其中记录了设备的全部信息,包括设备的设置参数、状态以及操作函数指针,每一个帧缓冲设备必须对应一个fb_info结构体。

2、fb_var_screeninfo 和 fb_fix_screeninfo

struct fb_var_screeninfo {
	__u32 xres;			/* 可视分辨率 */
	__u32 yres;
	__u32 xres_virtual;		/* 虚拟分辨率 */
	__u32 yres_virtual;
	__u32 xoffset;			/* 虚拟到可视之间的偏移 */
	__u32 yoffset;		

	__u32 bits_per_pixel;		/* 每个像素点占用的位数 */
	__u32 grayscale;		/* 非0时指灰度值 */

	struct fb_bitfield red;		/* fb内存的RGB位域 */
	struct fb_bitfield green;
	struct fb_bitfield blue;
	struct fb_bitfield transp;	/* 透明度 */	

	__u32 nonstd;			/* 非0时代指非标准像素格式 */

	__u32 activate;			/* see FB_ACTIVATE_* */

	__u32 height;			/* 高度 mm */
	__u32 width;			/* 宽度 mm */

	__u32 accel_flags;		/* (OBSOLETE) see fb_info.flags */

	/* 时序: 除pixel以外,其他的都以像素时钟为单位 */
	__u32 pixclock;			/* 像素时钟(皮秒) */
	__u32 left_margin;		/* 行前肩:从行同步信号到有效数据开始的时钟数 */
	__u32 right_margin;		/* 行后肩:从有效数据末尾到行同步信号的时钟数 */
	__u32 upper_margin;		/* 帧前肩:从帧同步信号到有效行开始的行数 */
	__u32 lower_margin;             /* 帧后肩:从有效行末尾到帧同步信号的行数 */
	__u32 hsync_len;		/* 行同步信号占用的时钟数 */
	__u32 vsync_len;		/* 帧同步信号占用的行数 */
	__u32 sync;			/* see FB_SYNC_*		*/
	__u32 vmode;			/* see FB_VMODE_*		*/
	__u32 rotate;			/* 旋转角度 */
	__u32 reserved[5];		/* 保留备用 */
};

struct fb_fix_screeninfo {
	char id[16];			/* 标识符 */
	unsigned long smem_start;	/* framebuffer的物理起始地址 */
	__u32 smem_len;			/* framebuffer的长度 */
	__u32 type;			/* see FB_TYPE_*		*/
	__u32 type_aux;			/* 隔行扫描参数 */
	__u32 visual;			/* see FB_VISUAL_*		*/ 
	__u16 xpanstep;			/* zero if no hardware panning  */
	__u16 ypanstep;			/* zero if no hardware panning  */
	__u16 ywrapstep;		/* zero if no hardware ywrap    */
	__u32 line_length;		/* 一行的字节数 */
	unsigned long mmio_start;	/* 内存映射I/O的物理起始地址 */
	__u32 mmio_len;			/* 内存映射I/O的长度 */
	__u32 accel;			
	__u16 reserved[3];		/* 保留备用 */
};
这两个结构体分别记录了显示器可以修改和不可修改的信息,这些数据成员需要在驱动程序中初始化。其中fix.visual代表显示器使用的色彩模式,Linux中支持的色彩模式如下:

#define FB_VISUAL_MONO01		0	/* 黑白. 1=Black 0=White */
#define FB_VISUAL_MONO10		1	/* 黑白. 1=White 0=Black */
#define FB_VISUAL_TRUECOLOR		2	/* 真彩色,由红绿蓝三基色构成*/
#define FB_VISUAL_PSEUDOCOLOR		3	/* 伪彩色,采用索引颜色 */
#define FB_VISUAL_DIRECTCOLOR		4	/* 查表显示 */
#define FB_VISUAL_STATIC_PSEUDOCOLOR	5	/* 只读的伪彩色 */

fb_bitfield结构体描述每一个像素在显示缓冲区中的组织方式。

struct fb_bitfield {
	__u32 offset;			/* 位域偏移 */
	__u32 length;			/* 位域长度 */
	__u32 msb_right;		/* != 0 : 最高有效位在右边 */ 
};

3、fb_ops

struct fb_ops {
	/* 打开/释放 */
	struct module *owner;
	int (*fb_open)(struct fb_info *info, int user);
	int (*fb_release)(struct fb_info *info, int user);

	/* 下面两个函数是非线性布局的/常规内存映射无法工作的缓冲设备需要的接口 */
	ssize_t (*fb_read)(struct fb_info *info, char __user *buf,
			   size_t count, loff_t *ppos);
	ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,
			    size_t count, loff_t *ppos);

	/* 检测可变参数并调整到支持的值 */
	int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);

	/* 根据info->var设置video模式 */
	int (*fb_set_par)(struct fb_info *info);

	/* 设置颜色寄存器 */
	int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
			    unsigned blue, unsigned transp, struct fb_info *info);

	/* 批量设置颜色寄存器 */
	int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);

	/* 清屏 */
	int (*fb_blank)(int blank, struct fb_info *info);

	/* pan display */
	int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);

	/* 绘制一个矩形 */
	void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
	/* 拷贝数据 */
	void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
	/* 绘制一幅图像 */
	void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);

	/* 绘制光标 */
	int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);

	/* 旋转显示 */
	void (*fb_rotate)(struct fb_info *info, int angle);

	/* 等待blit空闲(可选) */
	int (*fb_sync)(struct fb_info *info);

	/* ioctl函数(可选) */
	int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
			unsigned long arg);

	/* 32位的compat ioctl(可选) */
	int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
			unsigned long arg);

	/* fb特定的mmap */
	int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);

	/* 根据var得到显示器的功能信息 */
	void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
			    struct fb_var_screeninfo *var);

	/* 销毁fb */
	void (*fb_destroy)(struct fb_info *info);
};

fb_ops是驱动编写人员应该实现的底层函数接口。

4、tccfb_info

struct tccfb_info {
	struct fb_info		*fb;  // fbi结构体
	struct device		*dev;

	//struct tccfb_mach_info *mach_info;

	/* raw memory addresses */
	dma_addr_t		map_dma;	/* physical */
	u_char *		map_cpu;	/* virtual */
	u_int			map_size;

	/* addresses of pieces placed in raw buffer */
	u_char *		screen_cpu;	/* virtual address of buffer */
	dma_addr_t		screen_dma;	/* physical address of buffer */

	u_int			imgch;

	struct tccfb_platform_data *pdata;
#ifdef CONFIG_HAS_EARLYSUSPEND
    struct early_suspend early_suspend;
    struct early_suspend earlier_suspend;
#endif
};

二、framebuffer注册流程分析

static struct platform_driver tccfb_driver = {  // 底层函数接口
	.probe		= tccfb_probe,
	.remove		= tccfb_remove,
	.suspend	= tccfb_suspend,
	.shutdown	= tccfb_shutdown,
	.resume		= tccfb_resume,
	.driver		= {
		.name	= "tccxxx-lcd",
		.owner	= THIS_MODULE,
	},
};

static int __init tccfb_init(void)
{
    printk(KERN_INFO " %s (built %s %s)\n", __func__, __DATE__, __TIME__);

	fb_power_state = 1;

	tca_fb_init();   // 初始化控制器

#ifdef TCC_VIDEO_DISPLAY_BY_VSYNC_INT   // 初始化锁
	spin_lock_init(&vsync_lock) ;
	spin_lock_init(&vsync_lockDisp ) ;
#endif

	return platform_driver_register(&tccfb_driver);
}

static void __exit tccfb_clea
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值