DRM

 DRM驱动

  前一篇博文的图4内核里面是drm驱动,注意到和图3的区别,单独的FB driver已经没有了,而是被集合到了drm驱动里面。在一些只要求进行进本显示的嵌入式系统上,依然会使用单独的framebuffer驱动,而对于内核中有3D加速的AMD、intel等驱动,内核里面和显示有关的功能已经集合到了drm驱动里面。在AMD/intel显卡+Xorg+3D这样配置的开源Linux系统上,Xorg并不使用,但是系统中仍然有/dev/fb0这样的设备节点,如果我们在桌面环境下“cat xxx >/dev/fb0”,系统不会有变化。然而如果将xorg.conf的Driver修改成“fbdev”,重启Xorg,在执行操作,能够看到有变化(关于Xorg.conf可以参考"man xorg.conf",或者查看这个页面)。或者切换到控制台终端“Ctrl+Alt+Fn”,然后运行同样的命令,就能够看到屏幕上的内容发生了变化,在这篇博文的第一节的程序有一个FBIOPAN_DISPLAY调用,这个调用会使得显卡的Crtc指向的显存地址发生变化而将当前的显示区域切换到fb0设备节点对应的区域,因此上面的程序运行即使在X桌面环境下运行,也能够看到屏幕发生了变化。这提示我们在核外X驱动正常运行的情况下,核外X驱动并不使用framebuffer驱动(实际上drm驱动注册的frambuffer设备只是给内核使用),在X启动运行后,不使用framebuffer 管理的那片内存的内容作为显示输出,而是使用了另外一片内存。

  当前的Linux系统上内核的显卡驱动称为drm驱动,在通常的linux内核发行版上,我们使用lsmod命令查看内核模块,能够看到类似下面的信息:

  radeon                933054  3

  ttm                    45600  1 radeon

  drm_kms_helper         22468  1 radeon

  drm                   162230  5 radeon,ttm,drm_kms_helper

  i2c_algo_bit            5055  2 i2c_gpio,radeon

  机器使用的是AMD的radeon显卡,上面显示了当前系统内核和显卡驱动相关的模块,drm模块是内核drm驱动的基础架构,所有drm显卡驱动都会加载这个内核模块,ttm是ttm内核管理机制,drm_kms_helper是内核模式的基础框架代码,i2c_algo_bit是显卡上操作i2c设备使用的模块,显卡上的i2c设备主要包括了connector,encoder以及pll时钟芯片。Drm内核驱动的代码在内核源码目录drivers/gpu/drm下面。加载了drm驱动后,在/dev目录下面会生成如下设备节点:

  /dev/char/226:0 -> ../dri/card0

  /dev/char/226:64 -> ../dri/controlD64

  /dev/dri/card0

  /dev/dri/controlD64

  其中/dev/dri/card0是操作gpu的接口,发送命令等操作都是通过对这个设备节点进行的。/dev/dri/controlD64是kms相关的设备节点。

  通常核外的驱动程序使用ioctl调用同内核进行交互,linux系统上核外对drm的ioctl进行了一层封装,即libdrm,应用程序通过libdrm调用操作硬件,关于drm的调用,这里有一些比较好的示例代码 https://github.com/dvdhrm/docs,这份代码主要调用libdrm进行模式设置,有详细的注释。

 

  Linux下的图形驱动的主要部分是核外部分,核外部分包括了xorg exa驱动以及mesa 3d 驱动,exa是传统的2D加速框架,mesa 3d驱动则是针对3D驱动的硬件加速。由于历史原因,在Fedora 16以及更早和稍后的系统上,即使现在硬件上不包含单独的2D部件2D功能是由3D部件实现的,但是2D驱动和3D仍然是分离的。

3. EXA驱动

  早期的2D加速驱动使用的是XAA、KAA架构,但是随着composite扩展的加入,新的exa框架产生了,EXA删除掉了原来2D驱动中的三角形绘制、线绘制等一些现在没什么用处的功能,取而代之的是三个加速功能:矩形填充(Solid)、拷屏操作(Copy/Blt)和混合操作(Composite)。

  “XFree86 server 4.x Design (DRAFT)”文详细介绍xorg驱动需要提供的接口,EXA驱动通过扩展的形式添加并编译到xorg驱动中。在后续的blog文章里面将介绍exa驱动接口,并使用radeon的exa驱动来描述显卡驱动编程过程。

4. 3D驱动

  在linux环境中,我们可以通过glxinfo命令插卡3D硬件图形加速是否可用。比如在radeon显卡上glxinfo的输出包含以下内容:

  OpenGL renderer string: Gallium 0.4 on AMD CEDAR

  这里显示使用AMD CEDAR核心的显卡进行opengl 3d加速,如果硬件加速不可用,则应当是“vmware on llvmpipe”这类字眼。

  开源的OpenGL实现是mesa,mesa向上提供OpenGL接口,下层通过硬件的mesa驱动和硬件交互。GLX是X协议的扩展,用于OpenGL和X的交互(GLX规范)。在mesa源码包中包含了大量的opengl示例程序,包括OpenGL红宝书中的示例代码、调用GLUT或者GLX接口的代码、调用EGL的代码等。

图1

  图1显示了一个3D应用程序运行的过程,OpenGL绘图程序命令被用户空间的mesa驱动翻译成对应GPU的绘图命令放入命令缓冲区中,其他的如顶点信息/纹理信息/索引信息放入到相应缓冲中,mesa驱动为每个应用程序保存了当前的绘图状态,当发生3D程序切换,当前状态被保存下来,当下次调度该程序运行的时候,先恢复该程序的绘图状态到硬件上,然后继续执行命令缓存中的命令。当用户空间调用发送命令到内核的时候,内核驱动对硬件进行编程从该程序的命令缓冲区中取命令开始执行。这个过程是在dri框架下实现的,这里的所有绘制过程并不请求X,OpenGL直接将命令发送给硬件。GLX在初始化窗口,申请buffer和切换buffer的时候才会和X交互。

  图1来自文献“Graphic Engine Resource Management”,这篇文章描述了对早期的内核drm驱动做的一些改进,在这篇硕士论文“A Fair-Share Scheduler for the Graphics Processing Unit对一些问题有更清楚的描述。

 

其他参考资料:

DRM and KMS kernel modules 描述了drm驱动和kms的一些细节。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值