基于DirectFB的framebuffer底层驱动及应用程序架构原理分析
来源:互联网 发布:平面效果图设计软件 编辑:程序博客网 时间:2024/05/16 15:31
本文作者为:铁匠Smith 先生
转载请在显著位置注明出处和链接,否则保留追究相关事务之权利。
一、DirecfFB架构下应用层fbdev系统的初始化
对任何一个dfb应用程序,它在初始化时一定会调用下面两句:
/* DirectFB init */
DirectFBInit( &argc, &argv);
DirectFBCreate(&dfb);
第一步,DirectFBInit主要完成directFB配置的一些初始化。主要包括读取环境变量DIRECTFBPATH,读取directfbrc文件,获取系统配置和用户配置、处理命令行等。
读取到的配置信息保存在dfb_config全局变量中。这样,后面的程序可以通过dfb_config,获取配置信息,不需要自己去读取。
第二步,DirectFBCreate主要是在配置已经读取的基础上,完成一系列初始化,并将各种需要的信息保存在IDirectFB指向的数据结构中.
其中,对fbdev的初始化流程为:调用dfb_core_create-------->dfb_system_lookup.
dfb_system_lookup函数主要是根据系统库目录,读取和加载系统信息。这里的系统,指的是图形系统,一般frame buffer设备(fbdev)、x11等。
系统库目录是以如下这种宏的形式指定的:
DEFINE_MODULE_DIRECTORY( dfb_core_systems, "systems", DFB_CORE_SYSTEM_ABI_VERSION );
例如:
root@Danny:/opt/WorkDir/SHLib/directfb-1.4-0# ls
gfxdrivers inputdrivers interfaces systems wm
root@Danny:/opt/WorkDir/SHLib/directfb-1.4-0/systems# ls
libdirectfb_fbdev.so
系统目录为:/opt/WorkDir/SHLib/directfb-1.4-0/systems.
要加载的系统插件为:libdirectfb_fbdev.so
DFB图形系统相关的大致软件架构如下图所示:
二、DirecfFB架构下应用层图形系统fbdev与帧缓冲驱动通信及内存映射的建立
在上节的dfb_system_lookup函数里会调用direct_modules_explore_directory( &dfb_graphics_drivers ),最后会调用dlopen( )函数。
根据dlopen的性质,在dlopen函数返回前,它会调用被__attribute__((constructor))修饰的函数。
在core_system.h里我们可以看到如下定义:
前面我们已经分析知道,要加载的系统插件为:libdirectfb_fbdev.so
在fbdev.c文件的开始,可以找到如下宏:
DFB_CORE_SYSTEM( fbdev )
可按上面的代码定义进行展开。
在上图的代码调用在dlopen返回前完成后,实际上完成了注册fbdev的systemfuncs.
在dfb核心初始化时, 会调用dfb_core_part_initialize,遍历各个core part,完成各个core的初始化,fbdev属于system 核心组件。
(core part是通过DFB_CORE_PART( )宏来注册的), 如DFB_CORE_PART( system_core, SystemCore );
对于system核心组件来说,DFB初始化时会调用到dfb_system_core_initialize:
system_funcs->Initialize( core, &system_data );
fbdev属于core system, 会调用自己的system_initialize函数。
本节主要是介绍system_initialize函数所做的工作,主要可概括为以下几个部分:。
(1)调用dfb_fbdev_open()打开framebuffer设备(如:“/dev/fb0”)。
(2)调用ioctl( dfb_fbdev->fd, FBIOGET_FSCREENINFO, &shared->fix)获取显卡内存和类型等固定信息;
(3) 把framebuffer设备文件映射进虚拟内存,并保存内存基址:
dfb_fbdev->framebuffer_base = mmap( NULL, shared->fix.smem_len,
PROT_READ | PROT_WRITE, MAP_SHARED,
dfb_fbdev->fd, 0 );
(4)调用dfb_surface_pool_initialize初始化平面内存池。
(4)通过ioctl获取屏幕可变信息和调色板等信息。
三、DirecfFB架构下应用层图形gfxdriver架构及其与应用层图形系统fbdev的映射以及gfxdriver
gfxdriver架构如下图所示:
在gfxdriver初始化时,也就是调用driver_init_driver( card, &card->funcs, card->driver_data, card->device_data, core )函数时,会初始化driverdata。
四、DirecfFB架构下应用层图形系统fbdev与帧缓冲驱动通信:内存分配的时机和执行
前面说过,对任何一个dfb应用程序,它在初始化时一定会调用下面这句:DirectFBCreate(&dfb)---》IDirectFB_Construct------》完成一系列函数指针的安装,如:IDirectFBSurface_DrawRectangle----》dfb_gfxcard_drawrectangle。在dfb_gfxcard_drawrectangle函数里,会对显卡的状态进行检查并获取当前状态:
if (rect->w <= card->limits.dst_max.w && rect->h <= card->limits.dst_max.h && dfb_gfxcard_state_check( state, DFXL_DRAWRECTANGLE ) && dfb_gfxcard_state_acquire( state, DFXL_DRAWRECTANGLE )) { hw = card->funcs.DrawRectangle( card->driver_data, card->device_data, rect ); dfb_gfxcard_state_release( state ); }
接着会触发如下的函数调用
dfb_gfxcard_state_acquire
---》dfb_surface_buffer_lock
----》dfb_surface_pools_allocate
--->dfb_surface_pools_negotiate( /* Build a list of possible pools being free or out of memory */TestConfig ---))-
该函数会调用TestConfig检查是否有足够的显存
----》然后进行内存的分配调用:
/* Try to do the allocation in one of the pools */ for (i=0; i<num_pools; i++) { CoreSurfacePool *pool = pools[i]; D_MAGIC_ASSERT( pool, CoreSurfacePool ); ret = dfb_surface_pool_allocate( pool, buffer, &allocation ); if (ret == DFB_OK) break; /* When an error other than out of memory happens... */ if (ret != DFB_NOVIDEOMEMORY) { D_INFO( "%s( -> Allocation in '%s' failed for %s!)\n", __func__, pool->desc.name, DirectFBErrorString(ret) ); /* ...forget about the pool for now */ pools[i] = NULL; }
------》AllocateBuffer
------》fbdevAllocateBuffer
fbAlloc.flags = FBMAN_ALLOCATE_SURFACE | FBMAN_COMMON_SURFACE; fbAlloc.pid = dfb_fbdev->shared->master_pid; if (ioctl( dfb_fbdev->fd, FBIO_ALLOCFB, &fbAlloc) < 0){ //D_INFO("%s([Frame Buffer Memory] out of memory (size %d)!)\n", __func__, fbAlloc.size); ret = DFB_NOVIDEOMEMORY; }else{ ret = DFB_OK; }
在ioctl后,帧缓冲内存的分配就交给驱动层内核去实现了,并最终映射到物理内存。
五、DirecfFB架构下帧缓冲驱动层内存管理的实现:内存分配实例分析。
接到用户层的内存分配请求:
case FBIO_ALLOCFB: {T_fb_allocate allocFB; int ret;if ( copy_from_user(&allocFB, (void *)arg, sizeof(allocFB)) ) {retval = -EFAULT;break;}ret = AllocateFB(&allocFB); retval = (copy_to_user( (void *)arg, &allocFB, sizeof(allocFB) ) ? -EFAULT : 0 ); retval = (ret ? -EFAULT : retval); } break;
于是去调用AllocateFB函数。
详细内容请参考下一篇文章: 基于Linux伙伴算法和DirecfFB架构的帧缓冲驱动层内存管理的一个实现。
- 基于DirectFB的framebuffer底层驱动及应用程序架构原理分析
- 基于framebuffer的驱动分析
- 基于framebuffer的驱动分析
- 基于MTD的NANDFLASH设备驱动底层实现原理分析
- 基于MTD的NANDFLASH设备驱动底层实现原理分析 .
- Linux FrameBuffer分析之编写基于FrameBuffer接口的应用程序
- 基于framebuffer(fb)的驱动分析
- 基于MTD的NANDFLASH设备驱动底层实现原理分析(一)
- 基于MTD的NANDFLASH设备驱动底层实现原理分析(二)
- 基于MTD的NANDFLASH设备驱动底层实现原理分析(三)
- 基于MTD的NANDFLASH设备驱动底层实现原理分析(四)
- 基于MTD的NANDFLASH设备驱动底层实现原理分析(五)
- 基于MTD的NANDFLASH设备驱动底层实现原理分析(六)
- 基于MTD的NANDFLASH设备驱动底层实现原理分析(七)
- 基于MTD的NANDFLASH设备驱动底层实现原理分析(一)
- 基于MTD的NANDFLASH设备驱动底层实现原理分析(二)
- 基于MTD的NANDFLASH设备驱动底层实现原理分析(三)
- 基于MTD的NANDFLASH设备驱动底层实现原理分析(四)
- zoj 1369
- TypeError: 'str' object is not callable
- Apache common-pool, common-dbcp源码解读与对象池原理剖析
- Oracle常用查看表结构命令
- Java发送邮件简单实例
- 基于DirectFB的framebuffer底层驱动及应用程序架构原理分析
- 怎么在Datagridview查询的结果中进行修改-我只是感慨您从那学的??
- QListWidget的基本使用
- 理解ThreadLocal
- 求n!
- fedora编译VLC源码
- common-pool的使用
- arm-linux下移植的qt和tslib那些鸟事
- 关于MinGW GCC编译C++程序动态链接到libgcc_s_dw2-1.dll的问题