1.帧缓冲的基本原理 通过 framebuffer ,应用程序用 mmap 把显存映射到应用程序虚拟地址空间,将要显示的数据写入这个内存空间就可以在屏幕上显示出来; 驱动程序分配系统内存作为显存;实现 file_operations 结构中的接口,为应用程序服务;实现 fb_ops 结构中的接口,控制和操作 LCD 控制器; 驱动程序将显存的起始地址和长度传给 LCD 控制器的寄存器 (一般由 fb_set_var 完成) 。 LCD 控制器会自动的将显存中的数据显示在 LCD 屏上。 2. register_framebuffer(struct fb_info *fb_info) unregister_framebuffer(struct fb_info *fb_info) 底层驱动程序的工作基本上是填充 fb_info 结构,然后注册它 3. OMAP 的 DSS显示 DSS(Display sub system)显示子系统 显示子系统的库在drivers/video/omap2/dss目录中,主要包含了 core.c, dispc.c, display.c, dpi.c, dss.c ,manager.c omapdss.c, overlay.c venc.c core.c中定义了platform_driver static struct platform_driver omap_dss_driver = { .driver = { .name = "omapdss", .owner = THIS_MODULE, }, } 它和arch/arm/mach-omap2中定义的平台设备相匹配 static struct platform_device my_dss_device = { .name = "omapdss", .id = -1, .dev = { .platform_data = &my_dss_data, }, }; 文件系统的信息包含在以下目录中 / # ls sys/devices/platform/omapdss/ uevent modalias subsystem power driver manager0 manager1 overlay0 overlay1 overlay2 microamps_requested_vdda_dac display2 display1 display0 ---------------------------------------------------- overlay0目录中为基本显示层的信息 overlay1和overlay2分别目录中分别是两个叠加显示层的信息 manager0和manager1中则提供了管理方面的功能 查看sys文件系统 / # cat sys/devices/platform/omapdss/overlay0/name gfx gfx为graphics的含义,表示overlay0的名称为图形层,文件enable是一个可又控制的 # echo 0 > sys/devices/platform/omapdss/overlay0/enabled 关屏 # echo 1 > sys/devices/platform/omapdss/overlay0/enabled 开屏 4. 主显示驱动的framebuffer drivers/video/omap2/omapfb omafb.c, omapfb-sysfs.c, omapfb-ioctl.c, omapfb-main.c omapfb-main.c定义了platform_driver #define MODULE_NAME "omapfb" static struct platform_driver omapfb_driver = { .probe = omapfb_probe, .remove = omapfb_remove, .suspend = omapfb_suspend, .resume = omapfb_resume, .driver = { .name = MODULE_NAME, .owner = THIS_MODULE, }, }; 与arch/arm/plat-omap/fb.c中的platform_device相匹配 static struct platform_device omap_fb_device = { .name = "omapfb", .id = -1, .dev = { .dma_mask = &omap_fb_dma_mask, .coherent_dma_mask = ~(u32)0, .platform_data = &omapfb_config, }, .num_resources = 0, }; omapfb-main.c的调用 static int omapfb_probe(struct platform_device *pdev) { struct omapfb2_device *fbdev = NULL; omapfb_create_framebuffers(fbdev);/*调用 framebuffer_alloc 为fb_info结构体分配内存*/ } static int omapfb_create_framebuffers(struct omapfb2_device *fbdev) { struct fb_info *fbi; struct omapfb2_device *fbdev = NULL; fbdev = kzalloc(sizeof(struct omapfb2_device), GFP_KERNEL); fbi = framebuffer_alloc(sizeof(struct omapfb_info), fbdev->dev); ... omapfb_fb_init(fbdev, fbdev->fbs[i]);//初始化 //注册framebuffer for (i = 0; i < fbdev->num_fbs; i++) { r = register_framebuffer(fbdev->fbs[i]); return r; } } static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi) { fbi->fbops = &omapfb_ops; } static struct fb_ops omapfb_ops = { .owner = THIS_MODULE, .fb_open = omapfb_open, .fb_release = omapfb_release, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_blank = omapfb_blank, .fb_ioctl = omapfb_ioctl, .fb_check_var = omapfb_check_var, .fb_set_par = omapfb_set_par, .fb_pan_display = omapfb_pan_display, .fb_mmap = omapfb_mmap, .fb_setcolreg = omapfb_setcolreg, .fb_setcmap = omapfb_setcmap, /*.fb_write = omapfb_write,*/ };