今天是值得纪念的一天。忙了几天,终于将虚拟Framebuffer调试好了,这样Qt就可以在我们平台上跑了。
虽然我们平台上基于Linux平台的,但是显示设备底层驱动并不是按照Framebuffer的规范来写的,而是有自己特定驱动方式,由于并不是开源软件,所以不好详细阐述。
在新平台架构,我们选用Qt作为GUI开发工具。众所周知,Qt是基于Framebuffer的,所以我们只有两条路可走。一、向芯片厂商要显示设备的硬件资料,自己开发其Framebuffer驱动,这周期将会拉得很长;二、在原驱动基础上建立一个Framebuffer虚拟层,这样上层应用虽然是调用Framebuffer的接口,但显示数据归根结底还是交给原Surface驱动来处理。显然我们选择的是第二种方案,简单明了而且不用背负太多风险。
明确了方向,便开始去了解Framebuffer的驱动流程,网上有一篇文章《FrameBuffer 原理、实现与应用 》说得极其精简扼要,在此对其作者深表敬意,希望我有朝一日能写出这样流程清晰、通俗易懂的技术文档。接着看Linux内核中关于framebuffer的驱动,那里面真的是精彩,硬件抽象性被诠释得淋漓尽致。软件common的操作都是在fbmem.c、fbcon.c中实现,而硬件初始化部分则根据硬件设备的不同而独立,开发一款新设备的framebuffer驱动,只需关心硬件初始化即可。当时看这部分驱动入了迷,几乎忘了正事。
有了一定的准备,自然我们知道即将要做的事情。Virtual FB,如其名,并不是真实的设备,所以我们只需要处理好fb_ioctl和fb_mmap即可。前者将显示设备相应参数finfo、vinfo等赋给registered_fb[0],这里特别需要留意的是vinfo->smem_start,这个参数事实上对应于真实显示设备显存的物理地址这里我们将它替换为surface->mem.buffer的物理地址。而后者,fb_mmap中对显存的映射是按照一个页Page为单位来对齐的,而surface->mem.buffer的分配是按照4字节对齐的,明白这一点,我们分配surface memory时按照Page为单位对齐就行了,这样不会出现图像错位的现象。
总之,Virt FB的原理是非常简单的,而实际上在后来的开发过程中屡屡碰到多个难题。首先是surface->mem.buffer的物理地址我们并不知晓,这段内存是在Heap上分配的,一开始我们用K1_to_PhysAddr来转换,但是那样还是不正确,最后还是老老实实看底层memory manage的代码才找到正确的接口,这样就花了一天时间。其次就是图像显示错位的现象,也是看Surface底层代码才明确修改相关参数来分配内存。叹一句,MIPS的内存管理体系真的是太复杂了,或许我已经习惯于ARM的内存管理模式。
无论如何,虚拟Fb的成功建立,Qt的成功运行,标志着新软件架构总算迈出了一步。但是还是不能轻心,根据需要,恐怕还要开发图形加速模块。而且显示性能尚未进行测试,如果不能达到每秒24帧,造成屏幕闪烁的话,那样依然要承受这个风险。
原软件平台显示模块:
新平台架构Virtual Fb模块:
阅读(4198) | 评论(4) | 转发(1) |