在上一小节《Linux GUI加速(1)_GUI系统概述》中,我们从应用层到kernel层大致分析了linux中的图形界面的构成,并在最后给出了kernel中DRM+KMS的软件显示框架以及accelerate logic+framebuffer+displayport的硬件结构。在这一子篇会将这两块内容详细展开。

本篇主要以Xilinx的xc7z010 的SOPC(zybo的开发板)为硬件平台,在以下几方面介绍:

  1. 以zynq 7000的逻辑资源(PL)搭建CRTC/Encoder/Connector硬件模块,以HDMI输出接口为例,介绍各个模块的接口特性(Framebuffer对应着物理的DDR部分);
  2. 会先给出DRM+KMS驱动框架下的主要模块,并针对上述硬件子模块分析对应的内核驱动部分;

DRI在片上系统的硬件构成

在各类SOC上,CRTC+Endode+Connector一般是集成在一个外设模块挂在系统总线上,以ARM为例,CRTC/Endoder等需要配置的外设模块,配置接口挂在APB总线,数据接口直接在AHB总线上,实现和Framebuffer的高速通信。

我们按照connector-->encoder-->crtc-->framebuffer的顺序倒过来介绍吧。

Connector

Connector其实就是和显示器连接的物理接口,常见的有VGA/HDMI/DVI/DP等。以HDMI为例,HDMI的接口信号主要由以下几组信号组成:

  1. 1组TMDS clock:差分时钟用于同步信号驱动;
  2. 3组TMDS data:查分数据传输视频信号;
  3. 1组I2C:用于EDID的获取;
  4. 1组音频总线;

(注:EDID全称是Extended Display Identification Data(扩展显示标识数据),目的是让视频信号输出设备输出前获取到存储在显示器内部的相关参数,如支持的分辨率、帧率、图像格式:RGB等,因此,整个输出的控制参数是由以下几个部分综合决定的:

  1. 通过connector读出的显示器支持的参数;
  2. 内核静态配置或devicetree传入的参数;
  3. 用户空间输入的参数)

HDMI类型的connector的任务就是输出显示器解码芯片所需的信号时序(主要是TMDS clock以及TMDS data)。

Encoder

Encoder比较好理解,在此处其实就是将一定格式的图像信号(如RGB、YUV等)编码成connector需要输出的信号。以HDMI为例,帧/行同步/显示内容都是通过TMDS data的串行总线输出的,那么并行的时序按照HDMI的标准编码为串行顺序则是Encoder的任务;

在本片中的XC7Z010 SOPC中Encoder+Connector如下:

CRTC

CRTC的任务是从Framebuffer中读出待显示的图像,并按照相应的格式输出给Encoder(本处的CRTC功能受限,相关格式配置只能通过配置硬件IP参数来改变,而不能通过内核)。在本例中,CRTC的硬件构成如下:

  1. AXI Video Direct Memory Access IP,通过AXI4总线获取DDR中Framebuffer数据,转为video-stream流格式的图像信息;
  2. Video Timing Controller IP,根据内核相应配置输出与视频流匹配的帧、行同步信号;
  3. AXI4-Stream to Video Out IP,将串行视频流转化为指定格式(IP配置)、指定分辨率(内核配置)的时序;

如下图:

Planes

Plane其实就是图层,实际输出的图像往往由多个图层叠加而成(想象一下photoshop的过程),比如主图层,显示光标的图层,其中有些图层由硬件加速模块生成,本例中不涉及,因此所有plane的相关操作都由软件实现,不涉及到任何硬件结构。

Framebuffer

Framebuffer对应着存储空间中的图像数据,此处对应硬件为DDR。

麻雀虽小,五脏俱全,次例程中的显示框架非常简单,但也包含了Framebuffer、CRTC、Planes、Encoder、Connector5个组件,片内硬件结构如下:

(PS:Dynamic Clock Generator生成显示子系统中各组件所需的驱动时钟,由Linux中的common clock framework统一管理)

DRI在Linux Kernel内的软件构成

按照DRI中几个组件分别介绍。

Framebuffer

我们知道Framebuffer是存储待显示图像信息的空间,因此,Framebuffer相关驱动中也就是对内存的操作,也就涉及到下面两个部分:

  • 对内存的管理(如GEM,for Graphics Execution Manager)
  • 内存中数据的更显方式(如DMA等)

对于第一点,GEM主要完成的事情是:

  • 对图像内存(显存)的空间开辟、释放;
  • 不同硬件对同一显存资源访问下的管理;

在Linux Kernel下的默认实现方式是CMA(Contiguous Memory Allocator)实现的,内核中对应代码是:

drivers/gpu/drm/drm_fb_cma_helper.c

这里稍微提一下CMA,CMA是个好东西,不仅在显存管理中有应用,在所有软硬件协 同处理中同样起这重要的作用。在一般的硬件(片内硬件加速模块)加速方案中,一般 实现方式如下:

  • linux kernel通过device-tree传入CMA配置所需的配置参数供CMA开辟相应的物理内存 空间(不被Cache到),并且相应的信息(物理空间首地址,size等)通过/dev/device 映射到用户空间;
  • DMA可以将加速模块预处理后的数据,根据已知参数(开辟的物理地址),传递到共享空间中供软件访问;

struct drm_framebuffer{

[...]

const struct drm_format_info *format;

[...]

}

  • format用于描述内存空间的组成,使用FOURCC(four-character code)制式,结构体中的pitch、offset 4个元素分别用于计算FOURCC4个图层中的内存长宽参数;(width和height用于描述显示的长宽参数);
  • DRI中支持下面这三种格式图像:
    • RGB:R/G/B分别存于不同的图层中;
    • YUV:不同压缩格式下的YUV存储方式不一;
    • C8:通过存储一块映射到RGB的映射表来实现图像信息存储;

framebuffer中在不同格式下所需要处理的图层的数量不一,具体的显存处理、格式解析主要在下列源码表中:

(显存管理)

drivers/gpu/drm/drm_framebuffer.c

drivers/gpu/drm/drm_gem.c

drivers/gpu/drm/drm_gem_cma_helper.c

drivers/gpu/drm/drm_fb_cma_helper.c

drivers/gpu/drm/drm_fb_framebuffer_helper.c

drivers/gpu/drm/drm_fb_fourcc.c

drivers/gpu/drm/drm_fb_cma_helper.c

drivers/gpu/drm/drm_fb_cma_helper.c

drivers/gpu/drm/drm_fb_cma_helper.c

(显存更新驱动接口)

drivers/gpu/drm/ati_pcigart.c

drivers/gpu/drm/ati_agpsupport.c

CRTC

CRTC虽然字面上意思为阴极射线显像管控制器,但CRT在普通显示设备中早已被淘汰,DRI中CRTC主要承担的作用:

  • 配置适合显示器的分辨率(kernel)并输出相应时序(hardware logic);
  • 扫描framebuffer送显到一个或多个显示设备中;
  • 更新framebuffer;

上述功能的主要通过struct drm_crtc_funcs和struct drm_crtc_helper_funcs这两个描述符实现:

drm_crtc_funcs中的两个重要句柄set_config和page_flip,其中,

set_config主要任务是:

  • 更新待送显的framebuffer中数据;
  • 根据(之前说的EDID读出支持的配置,device-tree对内核的配置以及用户空间的配置)参数配置软件参数并控制相应的寄存器(在本例中的VDMA及VTC的行列像素值等寄存器);
  • 将Encoder和connector的信息送给CRTC模块。

page_flip解决的问题很简单:

  • 必须得保证CRTC在读取framebuffer的时候,framebuffer里的帧不会被修改而产生窜帧的情况,采用的解决方式也是软硬件异构处理时常见的乒乓缓存的方式。

当page_flip完成后,会通过event通知用户层准备好下一帧的数据;

Planes

不涉及到GPU的话,planes没有那么复杂,主要是负责:

  • 主图层;
  • 移动光标图层;
  • 覆盖图层;

的创建、更新、销毁,其中图层的更新(多个图层的叠加),通过struct中的drm_plane_funcs来实现。

比较形象的例子如下:

Connector & Encoder

由于Connector和Encoder是SOC与外设直接打交道的地方,因此对应着不同SOC也是驱动适配修改最频繁的地方。DRI中这两块通过适配struct drm_connector_helper_funcs和struct drm_encoder_helper_funcs来实现。

Linux Kernel中的DRM+KMS中涉及到的点太多,由于能力和时间问题,没能遍历一遍,只能根据自己认为的重点讨论一边,但有些点我认为比较重要的,但没能深入了解,比如:

  • 硬件graphic加速和DRM的交互逻辑
  • CRTC的Atomic刷新机制的具体实现方式

等,如果大家能够交流一下自己的理解,那再好不过了。

linux kernel基本构成的内容有下列哪些项_Linux_GUI加速(2)_Linux中的DRM-KMS分析相关推荐

  1. linux kernel基本构成的内容有下列哪些项_Linux内核线程kernel thread详解

    内核线程 为什么需要内核线程 Linux内核可以看作一个服务进程(管理软硬件资源,响应用户进程的种种合理以及不合理的请求). 内核需要多个执行流并行,为了防止可能的阻塞,支持多线程是必要的. 内核线程 ...

  2. linux kernel基本构成的内容有下列哪些项_Linux下逻辑地址-线性地址-物理地址详解...

    一.逻辑地址转线性地址 机器语言指令中出现的内存地址,都是逻辑地址,需要转换成线性地址,再经过MMU(CPU中的内存管理单元)转换成物理地址才能够被访问到. 我们写个最简单的hello world程序 ...

  3. linux3.3内核去哪下载,Linux Kernel下载|Linux Kernel v3.18.3 稳定版 - 121下载站

    Linux Kernel是一种开源的操作系统内核,其遵循的是软件的开源性.自由性和免费性,Linux Kernel v3.15是目前的最新版本,也是最新版本中比较稳定的一个版本. Linux Kern ...

  4. Linux Kernel Panic报错解决思路

    Linux虽然没有蓝屏现象,不过Kernel报错有时也会让人头疼.有时重启后正常,linux系统运行一段时间后又down了,总不能出现问题就reboot啊.我从网上搜集一下资料,整理了出来,希望大家能 ...

  5. Linux Kernel PANIC(一)--概述(Hard Panic/Aieee和Soft Panic/Oops)

    本文信息 CSDN GitHub Linux Kernel PANIC(一)–概述(Hard Panic/Aieee和Soft Panic/Oops) LDD-LinuxDeviceDrivers/s ...

  6. The Linux Kernel Module Programming Guide 2.4 中文版

    The Linux Kernel Module Programming Guide 2.4 中文版 分类: Linux/os 2007-09-29 11:14 820人阅读 评论(0) 收藏 举报 T ...

  7. Android HAL层与Linux Kernel层驱动开发简介

    Android HAL层与Linux Kernel层驱动开发简介 阅读数:5070 近日稍微对Android中的驱动开发做了一些简要的了解,稍稍理清了一下Android驱动开发的套路,总结一下笔记. ...

  8. Linux中的DRM 介绍

    Linux中的DRM 如果在搜索引擎离搜索 DRM 映入眼帘的尽是Digital Rights Managemen,也就是数字版权加密保护技术. 这当然不是我们想要的解释.在类unix世界中还有一个D ...

  9. (DT系列五)Linux kernel 是怎么将 devicetree中的内容生成plateform_device【转】

    转自:https://blog.csdn.net/lichengtongxiazai/article/details/38942033 Linux kernel 是怎么将 devicetree中的内容 ...

最新文章

  1. [Nancy On .Net Core Docker] 轻量级的web框架
  2. 火车票上的星号暗藏玄机?!
  3. 云炬Qtpy5开发与实战笔记 3PyCharm添加PyUIC扩展——将.ui文件转换成.py文件
  4. 我的Go+语言初体验——【一、go+环境WIN10_100%成功安装(附-视频)】
  5. qsettings删除注册表_Qt QSettings读取注册表和ini | 学步园
  6. 嵌入式MODEM通迅技术
  7. T-SQL删除存储过程
  8. apache通过rewrite限制某个目录
  9. 【二分法】剑指offer:二维数组中的查找
  10. paip.python错误解决22
  11. 成为一名Java高级工程师需要掌握哪些技能
  12. html5的ajax上传图片,html5标准Ajax上传图片
  13. 在ajax中幸运抽奖,JS实现幸运抽奖页面
  14. 前端基础知识--Document的常用属性和常用函数
  15. 我与龙芯电脑的第一次亲密接触
  16. 详解JS中三元运算符的语法和常见用法
  17. 为什么那么容易转行软件测试,软件测试好学吗 大概要学多久
  18. Java正则表达式中,group()、group(i)、groupCount()含义详解
  19. 计算机组装安装主板的依靠什么初步定位,电脑维修高级全科班
  20. 解密古代五大美男的凄惨结局

热门文章

  1. caffe学习:通过研读classification.cpp了解如何使用caffe模型
  2. map传参上下文赋值的问题
  3. 如何将视频下载并且转码拼接
  4. eclipse使用git提交本地项目,提交至远程github上
  5. java多线程wait notify join
  6. Jquery 日期差函数 修改 对火狐进行兼容
  7. 编写一个判断素数的函数,在主函数输入一个整数时,输出是否素数的信息。...
  8. java 二叉树的深度、平衡二叉树、二叉树的下一个结点
  9. 循环神经网络基础介绍
  10. Linux与Windows比较出的20个优势