一、LCD驱动简析
1、Framebuffer
linux 应用程序通过操作 LCD 的显存来实现在 LCD 上显示信息,显存不能随意申请,驱动程序设置的显存和应用程序访问的显存要是同一片物理内存,因此 Framebuffer 机制诞生。
fb 将系统中所有跟显示有关的硬件和软件集合起来,,虚拟出一个 fb 设备。编写好 LCD 驱动以后会生成一个名为 /dev/fbX 的设备,应用程序通过访问这个设备就可以访问 LCD。
fb 的 file_operations 操作集定义在 drivers/video/fbdev/core/fbmem.c 文件。
linux 内核将所有的 Framebuffer 抽象为一个叫做 fb_info 的结构体,结构体包含了 Framebuffer 设备的完整属性和操作集合,每一个 Framebuffer 设备都必须有一个 fb_info。LCD 驱动就是构建 fb_info,并向系统注册。结构体定义在include/linux/fb.h 中:
struct fb_info {
atomic_t count;
int node;
int flags;
struct mutex lock; /* 互斥锁 */
struct mutex mm_lock; /* 互斥锁,用于fb_mmap和smem_*域*/
struct fb_var_screeninfo var; /* 当前可变参数 */
struct fb_fix_screeninfo fix; /* 当前固定参数 */
struct fb_monspecs monspecs; /* 当前显示器特性 */
struct work_struct queue; /* 帧缓冲事件队列 */
struct fb_pixmap pixmap; /* 图像硬件映射 */
struct fb_pixmap sprite; /* 光标硬件映射 */
struct fb_cmap cmap; /* 当前调色板 */
struct list_head modelist; /* 当前模式列表 */
struct fb_videomode *mode; /* 当前视频模式 */
#ifdef CONFIG_FB_BACKLIGHT /* 如果LCD支持背光的话 */
/* 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
#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; /* 虚拟内存基地址(屏幕显存) */
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 */
/* 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;
bool skip_vt_switch;