跳转至

Linux 图形子系统-DRM/KMS介绍

根据前两个章节的图形子系统的介绍,本章节将重点介绍 显示相关部分内容,也可以叫做图形显示框架部分,主要涉及DRM/KMS的内容,本文不涉及任何源代码,重点将原理工作进行说明。

1. 概念介绍

Linux 显示方案目前介绍2种:

  • FBDEV: Framebuffer Device
  • DRM/KMS: Direct Rendering Manager / Kernel Mode Setting

FBDEV

FBDEV是一种传统的显示框架,特点是简单,能够提供最基础的显示功能,但是无法满足一些底层硬件的现实要求。

DRM/KMS

DRM/KMS是一种主流的显示框架,在目前Linux使用比较多,能够支持更多高级的控制和特性。

特点/优势 FBDEV(Framebuffer Device) DRM/KMS(Direct Rendering Manager / Kernel Mode Setting)
显示方式 传统,用户空间操作 现代,内核空间操作
用户空间操作 直接控制帧缓冲,性能相对较差 通过标准图形API,硬件加速,性能更好
硬件兼容性 通常支持各种硬件但存在限制 通常具有更好的硬件兼容性,更多硬件支持
维护复杂性 需要更多维护和开发工作 更容易维护,提供标准化API和更多硬件支持
性能和功耗管理 较差 更好,支持硬件加速和功耗管理
适用场景 一些嵌入式系统,旧硬件 现代Linux系统,需要高性能和硬件加速的应用场景

为什么会出现DRM?

上面介绍了两个显示框架的不一样,大概了解一些优势和作用,主要是在目前显示外设的性能逐渐增强,3D渲染以及GPU的发展,FrameBuffer框架看起来似乎就有些落伍了, 最直接的体现,就是在传统的框架下,对于许多芯片显示外设的新特性如: 显示覆盖(菜单层级)、GPU加速、硬件光标等功能并不能得到很好得支持, 并且FrameBuffer框架将底层的显存通过用户空间/dev/fb接口,暴露给了用户空间, 这很容易导致不同的应用程序在操作显存时,产生访问冲突,而且这种方式看起来似乎不是那么安全。

这里查看图1.1 与图1.2进行对比,无DRM和有DRM进行说明。

1024px-Access_to_video_card_without_DRM.svg

图1.1 无DRM

1024px-Access_to_video_card_with_DRM.svg

图1.2 有DRM

从图1.1 中无DRM会看到存在一些问题,从图中可以看到两个用户程序,program A (X Server)去管理Video Card,这个时候X Sserver是独自访问这些资源,在这个时候program B 或者更多的程序去访问相同的一个硬件时候,就存在了一些竞争的问题。

再看看图1.2 有DRM,DRM是在Linux 内核的一部分,访问GPU的权利都需要通过DRM进行一个管理。DRM会获取独占访问GPU的权利,并负责初始化和维护命令队列,内存以及其他的硬件资源。程序需要访问GPU的时候需要给DRM发送请求,DRM将充当仲裁程序,并注意避免可能发生的冲突。

从上面2张图图只是展现了DRM对GPU的一个管理,其实DRM已经具有很多功能,对多个GPU的切换,缓冲区管理,内存共享对象和内存同步。扩展被赋予了特定的名称,例如图形执行管理器(GEM)或内核模式设置(KMS),当它们提供的功能被特别提及时,术语优先。但它们实际上是整个内核 DRM 子系统的一部分。

DRM(Direct Rendering Manager,直接图形管理器)

什么是KMS?

KMS(Kernel Mode Setting):也称作Atomic KMS它是一个在linux 4.2版本的kernel上才最终定性的技术。从字面意义上理解它要实现的功能比较简单即显示模式display mode的设置包括屏幕分辨率resolution、颜色深的color depth、屏幕刷新率refresh rate等等(它在Linux graphic的显示框架中主要被用来送显)。它的出现是为了解决最开始的DRM显示框架的缺点那时候Mode-Setting (包括更新画面、配置 display pipeline、screen resolution、color depth、refresh rate等) 是在 Userspace 中实现的这样做的缺点是

  • Rendering 和 Mode-Setting 会发生竞争;
  • 不统一缺少抽象不同的硬件平台各自为营;

2. 软件框架

DRM subsystem 图2.1

image-20230917164654532

图2.1 DRM subsystem

DRM可以分为三个部分:libdrm、KMS、GEM。

2.1 libdrm

Direct Rendering Manager library",是一个用户空间的开源库,主要用于与Linux图形子系统中的DRM(Direct Rendering Manager)交互。它提供了一组API和工具,允许应用程序和用户空间组件与内核中的DRM子系统进行通信和交互。也就是说libdrm是用户层与内核层DRM通信的一个标准工具,主要有以下功能:

  • 图形设备驱动程序的管理libdrm允许用户空间应用程序通过DRM接口与已加载的图形设备驱动程序进行通信。这包括查找和打开图形设备、查询设备信息以及与设备进行通信的能力。
  • 图形内存管理libdrm提供了API来管理图形设备的内存。它允许应用程序分配、映射和释放图形内存,以便进行渲染、纹理管理和其他图形操作。
  • 模式设置和显示配置libdrm还支持图形设备的显示模式设置和显示配置。这允许应用程序查询和配置显示器的分辨率、刷新率和显示模式,以满足不同的需求。
  • GPU加速和渲染操作libdrm提供了与GPU硬件加速相关的API,允许应用程序利用硬件加速进行渲染和计算操作。这对于图形性能的提升非常重要。
  • 多GPU管理libdrm支持多个GPU设备的管理,允许应用程序在多GPU系统上进行并行渲染和计算操作。
  • 硬件特定的DRM扩展libdrm还包括了一些硬件特定的扩展,以支持不同厂商的GPU和图形硬件。这些扩展允许更精确地配置和控制硬件。

2.2 KMS

KMS(Kernel Mode Setting)是作为DRM一个部分,是内核提供给应用层的DRM API的一部分,用户层可以通过libdrm进行访问。

KMS其中包含几个重要组件:

Framebuffer、Plane、CRTC、Encoder、Connector。

在这里插入图片描述

图2.1 KMS 组件实例

Framebuffer: 单个图层的显示内容,应用层和内核都可访问。硬件无关的基本元素,描述了图层显示内容的信息(width, height, pixel_format,pitch等)。这个是完全与硬件无关的一个元素。

Plane: 基本的显示控制单位,每个图像拥有一个Planes,Planes的属性控制着图像的显示区域、图像翻转、色彩混合方式等, 最终图像经过Planes并通过CRTC组件,得到多个图像的混合显示或单独显示的等等功能。

根据图2.1 中plane有多个,可以看到有光标,兔子图片,这样就是多个plane图层叠加送到CRTC组件当中。

这里需要注意有些图层是有硬件模块生成的,每个CRTC至少需要一个plane,对于plane 一共有三种:DRM_PLANE_TYPE_PRIMARY、DRM_PLANE_TYPE_OVERLAY、DRM_PLANE_TYPE_CURSOR。

CRTC : 从framebuffer中读取待显示的图像,并按照响应的格式输出给encoder。其承担的主要作用为:

  • 配置适合显示器的分辨率,并输出响应的时序。
  • 扫描framebuffer送到一个或多个显示器
  • 更新framebuffer

CRTC的工作,就是负责把要显示图像,转化为底层硬件层面上的具体时序要求,还负责着帧切换、电源控制、色彩调整等,可以连接多个 Encoder ,实现复制屏幕功能。

Encoder : 转换输出器,负责电源管理、显然输出需要不同的信号转换器,将内存的像素转换成显示器需要的信号。

Connector : Connector连接器负责硬件设备的接入,比如HDMI,VGA等,可以获取到设备EDID , DPMS连接状态等等。

image-20230917170105646

图2.2 KMS 内模块之间关系

2.3 GEM

GEM(Graphics Execution Manager)

GEM负责DRM下的内存管理和释放。主要是对 FrameBuffer 的管理,如内存的申请、释放、共享和同步(GPU和CPU之间内存)机制等。在图2.1 DRM subsystem 看到对PRIME是有一定的联系,对PRIME的Render Offload和Display Offload功能提供了支持。PRIME需要有效地管理图形内存以实现渲染和显示任务的协同工作,而GEM提供了这种内存管理的机制。

这里提到GEM的话,还有两外一种TTM,TTM(Translation Table Maps)是另一种用于图形内存管理的机制,更为复杂和功能更全面。它主要用于处理复杂的内存管理任务,如高级驱动程序功能、纹理管理和图形缓冲区的交换.

  • GEM更简单、轻量级,专注于基本的内存分配和映射,适用于常规的图形渲染任务。
  • TTM更复杂、功能更全面,旨在支持高级图形驱动程序功能,如纹理管理、缓冲区对象、GPU加速等。

3. 内核下的DRM

从以上内容已经大概了解DRM相关,DRM目前已经在内核已经作为一个标准子系统的存在,这里从驱动角度看看DRM。

image-20230917220231782

图3.1 Linux DRM Subsystem

在图3.1 中 有DRM Core /DRM DIS Core /DRM Panel Core/DRM Bridge Core

  • DRM Core(Direct Rendering Manager Core)
  • DRM Core是DRM子系统的核心组件,负责整体的图形硬件管理和用户空间接口。
  • DRM Core负责初始化和配置图形硬件,分配GPU资源,处理图形渲染请求,以及管理用户空间应用程序的访问权限。
  • DRM DIS Core(DRM Display Interface Subsystem Core)
  • DRM DIS Core是DRM子系统中的一个子组件,专门处理显示接口(例如HDMI、DisplayPort)的相关功能。
  • DRM Panel Core(DRM Display Panel Core)
  • DRM Panel Core是DRM子系统中的另一个子组件,用于管理液晶显示相关功能。
  • DRM Panel Core还支持不同面板类型的驱动程序,以适应各种硬件配置。
  • DRM Bridge Core(DRM Display Bridge Core)
  • DRM Bridge Core是DRM子系统中的一个组件,主要处理显示桥接器的相关功能。
  • 显示桥接器用于连接不同的显示设备,例如连接内部LCD面板和外部HDMI显示器的转换器。
  • DRM Bridge Core负责管理显示桥接器的初始化、配置和切换,以确保图形输出正确传递到目标显示设备。

对于一个驱动开发工程师来讲,对于调试不同的显示屏,那么对Panel 使用估计比较多;对于调试桥芯片相关,对于Bridge 使用比较多一些。

4. 总结

本章节主要对图形子系统中的显示部分做了简单的说明,提到内核中的DRM子系统,还有 KMS相关的内容,对于DRM的作用已经做了一定的说明,后续对于一个开发驱动来说,需要接触各种不一样的显示屏,显示屏包括各种接口LVDS,HDMI, MIPI DSI等等,那么后续将对显示屏的驱动相关做一些相关的调试相关记录。