(一)- DRM架构

一,DRM简介

linux内核中包含两类图形显示设备驱动框架:

  • FB设备:Framebuffer图形显示框架;

  • DRM:直接渲染管理器(Direct Rendering Manager),是linux目前主流的图形显示框架;

1,Frambebuffer驱动

Frambebuffer驱动具有以下特征:

  • 直接控制显卡的帧缓冲区,提供基本的显卡输出功能;

  • 使用一些内核数据结构和API来管理图形界面,并提供一组接口与用户空间的应用程序进行通信;

  • 相对简单,适合于嵌入式系统或者不需要高性能图形的应用场景。

2,DRM驱动

相比FB(Framebuffer)架构,DRM更能适应当前日益更新的显示硬件;

  • 提供一种分离的图形驱动架构,将硬件驱动程序、内核模块和用户空间驱动程序进行分离;

  • 支持多个应用程序同时访问显卡,并提供了更丰富的图形功能,例如硬件加速和3D加速;

  • 提供了一些内核接口,可以让用户空间应用程序与驱动程序进行交互;

  • 支持多显示器(Display)和多GPU的配置;

总之,一句话,DRM是Linux目前主流的图形显示框架,相比FB架构,DRM更能适应当前日益更新的显示硬。尽管FB退出历史舞台,但是并未将其遗弃,而是集合到DRM中,供部分嵌入式设备使用。

二,DRM框架

DRM是Linux目前主流的图形显示框架,相比FB架构,DRM更能适应当前日益更新的显示硬件。比如FB原生不支持多层合成,不支持VSYNC,不支持DMA-BUF,不支持异步更新,不支持fence机制等等,而这些功能DRM原生都支持。同时DRM可以统一管理GPU和Display驱动,使得软件架构更为统一,方便管理和维护

1,DRM模块划分

DRM从模块上划分,可以简单分为3部分:libdrm、KMS、GEM

1)libdrm

对底层接口进行封装,向上层提供通用的API接口,主要是对各种IOCTL接口进行封装。

2)KMS

Kernel Mode Setting,所谓Mode setting,其实说白了就两件事:更新画面和设置显示参数。

更新画面:显示buffer的切换,多图层的合成方式,以及每个图层的显示位置。

设置显示参数:包括分辨率、刷新率、电源状态(休眠唤醒)等。

3)GEM

Graphic Execution Manager,主要负责显示buffer的分配和释放,也是GPU唯一用到DRM的地方。

2,基本元素

DRM框架涉及到的元素很多,大致如下:

KMS:CRTC,ENCODER,CONNECTOR,PLANE,FB,VBLANK,property

GEM:DUMB、PRIME、fence

object

说明

plane

硬件图层,有的Display硬件支持多层合成显示,但所有的Display Controller至少要有1个plane

CRTC

对显示buffer进行扫描,并产生时序信号的硬件模块,通常指Display Controller

encoder

负责将CRTC输出的timing时序转换成外部设备所需要的信号的模块,如HDMI转换器或DSI Controller

connector

连接物理显示设备的连接器,如HDMI、DisplayPort、DSI总线,通常和Encoder驱动绑定在一起

framebuffer

Framebuffer,单个图层的显示内容,唯一一个和硬件无关的基本元素

VBLANK

软件和硬件的同步机制,RGB时序中的垂直消影区,软件通常使用硬件VSYNC来实现

property

任何你想设置的参数,都可以做成property,是DRM驱动中最灵活、最方便的Mode setting机制

DUMB

只支持连续物理内存,基于kernel中通用CMA API实现,多用于小分辨率简单场景

PRIME

连续、非连续物理内存都支持,基于DMA-BUF机制,可以实现buffer共享,多用于大内存复杂场景

fence

buffer同步机制,基于内核dma_fence机制实现,用于防止显示内容出现异步问题

 学习DRM驱动其实就是学习上面各个元素的实现及用法。

三,objects

在开始编写 DRM 驱动程序之前,我有必要对 DRM 内部的 Objects 进行一番介绍。因为这些 Objects 是 DRM 框架的核心,它们缺一不可。

上图蓝色部分则是对物理硬件的抽象,黄色部分则是对软件的抽象。虚线以上的为 drm_mode_object,虚线以下为 drm_gem_object。

这些 objects 的概念:

object

说明

crtc

RGB 信号发生源(TCON),显存切换控制器(Dislay Controller)

plane

Display Controller 的数据源通道,每个 crtc 至少要有一个 plane

encoder

RGB 信号转换器(DSI Contoller),同时也控制显示设备的休眠唤醒

connector

凡是能获取到显示参数的硬件设备,但通常和 encoder 绑定在一起

framebuffer

只用于描述显存信息(如 format、pitch、size 等),不负责显存的分配释放

property

atomic 操作的基础,任何想要修改的参数都可以做成 property,供用户空间使用

gem

负责显存的分配、映射和释放

 这些 objects 之间的关系:

通过上图可以看到,plane 是连接 framebuffer 和 crtc 的纽带,而 encoder 则是连接 crtc 和 connector 的纽带。与物理 buffer 直接打交道的是 gem 而不是 framebuffer。

需要注意的是,上图蓝色部分即使没有实际的硬件与之对应,在软件驱动中也需要实现这些 objects,否则 DRM 子系统无法正常运行。

四,drm_panel

drm_panel 不属于 objects 的范畴,它只是一堆回调函数的集合。但它的存在降低了 LCD 驱动与 encoder 驱动之间的耦合度。

耦合的产生:

(1)connector 的主要作用就是获取显示参数,所以会在 LCD 驱动中去构造 connector object。但是 connector 初始化时需要 attach 上一个 encoder object,而这个 encoder object 往往是在另一个硬件驱动中生成的,为了访问该 encoder object,势必会产生一部分耦合的代码。

(2)encoder 除了扮演信号转换的角色,还担任着通知显示设备休眠唤醒的角色。因此,当 encoder 通知 LCD 驱动执行相应的 enable/disable 操作时,就一定会调用 LCD 驱动导出的全局函数,这也必然会产生一部分的耦合代码。

为了解决该耦合的问题,DRM 子系统为开发人员提供了 drm_panel 结构体,该结构体封装了 connector & encoder 对 LCD 访问的常用接口。

于是,原来的 Encoder 驱动和 LCD 驱动之间的耦合,就转变成了上图中 Encoder 驱动与 drm_panel、drm_panel 与 LCD 驱动之间的“耦合”,从而实现了 Encoder 驱动与 LCD 驱动之间的解耦合。

为了方便驱动程序设计,通常都将 encoder 与 connector 放在同一个驱动中初始化,即 encoder 在哪,connector 就在哪。

五,如何抽象硬件

对于初学者来说,往往让他们迷惑的不是 DRM 中 objects 的概念,而是如何去建立这些 objects 与实际硬件的对应关系。因为并不是所有的 Display 硬件都能很好的对应上 plane/crtc/encoder/connector 这些 objects。下面我们就来一起学习,如何去抽象显示硬件到具体的 DRM object。

1,MIPI DSI 接口

下图为一个典型的 MIPI DSI 接口屏的硬件连接框图:

它在软件架构上与 DRM object 的对应关系如下图:

多余的细节不做介绍,这里只说明为何如此分配 drm object:

object

说明

crtc

RGB timing的产生,以及显示数据的更新,都需要访问 Dislay Controller 硬件寄存器,因此放在 Display Controller 驱动中

plane

对 Overlay 硬件的抽象,同样需要访问 Display Controller 寄存器,因此也放在 Display Controller 驱动中

encoder

将 RGB 并行信号转换为 DSI 串行信号,需要配置 DSI 硬件寄存器,因此放在 DSI Controller 驱动中

connector

可以通过 drm_panel 来获取 LCD 的 mode 信息,但是 encoder 在哪,connector 就在哪,因此放在 DSI Controller 驱动中

drm_panel

用于获取 LCD mode 参数,并提供 LCD 休眠唤醒的回调接口,供 encoder 调用,因此放在 LCD 驱动中

驱动参考:https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c

2,MIPI DPI 接口

DPI 接口也就是我们常说的 RGB 并行接口,Video 数据通过 RGB 并行总线传输,控制命令(如初始化、休眠、唤醒等)则通过 SPI/I2C 总线传输,比如早期的 S3C2440 SoC 平台。下图为一个典型的 MIPI DPI 接口屏的硬件连接框图:

该硬件连接在软件架构上与 DRM object 的对应关系如下图:

多余的细节不做介绍,这里只说明为何如此分配 drm object:

object

说明

crtc

RGB timing的产生,以及显示数据的更新,都需要访问 LCD Controller 硬件寄存器,因此放在 LCD Controller 驱动中

plane

LCDC 没有 Overlay 硬件,它只有一个数据源通道,被抽象为 Primary Plane,同样需要访问 LCDC 硬件寄存器,因此放在 LCDC 驱动中

encoder

由于 DPI 接口本身不需要对 RGB 信号做任何转换,因此没有哪个硬件与之对应。但是 drm objects 又缺一不可,因此实现了一个虚拟的 encoder object。至于为什么要放在 LCDC 驱动中实现,纯粹只是为了省事而已,你也可以放在一个虚拟的平台驱动中去实现该 encoder object。

connector

encoder 在哪,connector 就在哪,没什么好说的了

drm_panel

用于获取 LCD mode 参数,并提供 LCD 休眠唤醒的回调接口,供 encoder 调用,因此放在 LCD 驱动中

驱动参考:https://elixir.bootlin.com/linux/v5.0/source/drivers/gpu/drm/panel/panel-sitronix-st7789v.c

3,MIPI DBI 接口

DBI 接口也就是我们平时常说的 MCU 或 SPI 接口屏,这类屏的 VIDEO 数据和控制命令都是通过同一总线接口(I80、SPI接口)进行传输,而且这类屏幕必须内置 GRAM 显存,否则屏幕无法维持正常显示。

下图为一个典型的 DBI 接口屏的硬件连接框图:

该硬件连接在软件架构上与 DRM object 的对应关系如下:

上图参考 kernel4.19 tinydrm 软件架构。

object

说明

crtc

这类硬件本身不需要任何 RGB timing 信号,因此也没有实际的硬件与之对应。但是 drm objects 缺一不可,需要实现一个虚拟的 crtc object。由于更新图像数据的动作需要通过 SPI 总线发送命令才能完成,因此放在了 LCD 驱动中

plane

没有实际的硬件与之对应,但 crtc 初始化时需要一个 plane object 作为参数传递,因此和 crtc 放在一起

encoder

没有实际的硬件与之对应,使用虚拟的 encoder object。因为这类硬件并不是将 RGB 信号转换为 SPI 信号,而是根本就没有 RGB 信号源,也就无从谈起 encoder 设备。但是为了通知 LCD 休眠唤醒,需要调用 LCD 驱动的相应接口,因此放在 LCD 驱动中

connector

由于没有了 drm_panel,需要调用 LCD 接口来获取 mode 参数,因此放在 LCD 驱动中

 驱动参考:https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/tinydrm/ili9341.c

 

六,总结

  • 这 7 个 objects 缺一不可

  • framebuffer 只是负责描述显存信息,gem 则负责显存的分配/释放等操作

  • encoder 在哪里,connector 就在哪里

参考链接:

DRM(Direct Rendering Manager)学习简介-CSDN博客

DRM 驱动程序开发(开篇)_spi 何小龙 csdn-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/473647.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java基础-Java中的常用类(上)

(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹) 目录 String类 创建字符串 字符串长度 连接字符串 创建格式化字符串 String 方法 System类 常用方法 方…

Istio分布式链路监控搭建:Jaeger与Zipkin

分布式追踪定义 分布式追踪是一种用来跟踪分布式系统中请求的方法,它可以帮助用户更好地理解、控制和优化分布式系统。分布式追踪中用到了两个概念:TraceID 和 SpanID。 TraceID 是一个全局唯一的 ID,用来标识一个请求的追踪信息。一个请求…

探索Python网络请求新纪元:httpx库的崛起

文章目录 **探索Python网络请求新纪元:httpx库的崛起**第一部分:背景介绍第二部分:httpx库是什么?第三部分:如何安装httpx库?第四部分:简单的库函数使用方法1. 发送GET请求2. 发送POST请求3. 超…

vue使用List.reduce实现统计

需要对集合的某些元素的值进行计算时,可以在计算属性中使用forEach方法 1.语法:集合.reduce ( ( 定义阶段性累加后的结果 , 定义遍历的每一项 ) > 定义每一项求和逻辑执行后的返回结果 , 定义起始值 ) 2、简单使用场景:例如下面…

层归一化和批归一化

层归一化是针对某一样本的所有特征,批归一化是针对所有样本的某一特征。 计算公式:(当前值 - 均值)/ 标准差。 作用:缓解梯度消失和梯度爆炸的问题,并提高网络的泛化性能。 为什么Transform和BERT中使用层归…

vueRouter路由切换时实现页面子元素动画效果, 左右两侧滑入滑出效果

说明 vue路由切换时&#xff0c;当前页面左侧和右侧容器分别从两侧滑出&#xff0c;新页面左右分别从两侧滑入 效果展示 路由切换-滑入滑出效果 难点和踩坑 现路由和新路由始终存在一个页面根容器&#xff0c;通过<transition>组件&#xff0c;效果只能对页面根容器有效…

docker 安装之 windows安装

文章目录 1: 在Windows安装Docker报19044版本错误的时候&#xff0c;请大家下载4.24.1之前的版本&#xff08;含4.24.1&#xff09;2: Desktop-WSL kernel version too low3: docker-compose 安装 (v2.21.0)4: 配置镜像源 1: 在Windows安装Docker报19044版本错误的时候&#xf…

【GPTs】Gif-PT:DALL·E制作创意动图与精灵动画

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | GPTs应用实例 文章目录 &#x1f4af;GPTs指令&#x1f4af;前言&#x1f4af;Gif-PT主要功能适用场景优点缺点 &#x1f4af;小结 &#x1f4af;GPTs指令 中文翻译&#xff1a; 使用Dalle生成用户请求的精灵图动画&#…

FastGPT部署通义千问Qwen和智谱glm模型|OneAPI配置免费的第三方API

继这篇博客之后 从零开始FastGPT本地部署|Windows 有同学问&#xff0c;不想在多个平台申请API-Key&#xff0c;不好管理且要付费&#xff0c;有木有白嫖方案呀&#xff1f; 答&#xff1a;有啊。用硅基流动。 注册方法看这篇 【1024送福利】硅基流动送2000万token啦&#xff0…

JsonCpp

参考文档&#xff1a;https://zhuanlan.zhihu.com/p/374319504 json是一种轻量级数据交换格式&#xff0c;易于阅读和编写&#xff0c;也易于机器解析和生成。使用json格式可以方便地在各个系统之间传递数据。在c中&#xff0c;有许多开源的json库可以进行json的处理。比如&am…

7.揭秘C语言输入输出内幕:printf与scanf的深度剖析

揭秘C语言输入输出内幕&#xff1a;printf与scanf的深度剖析 C语言往期系列文章目录 往期回顾&#xff1a; VS 2022 社区版C语言的安装教程&#xff0c;不要再卡在下载0B/s啦C语言入门&#xff1a;解锁基础概念&#xff0c;动手实现首个C程序C语言概念之旅&#xff1a;解锁关…

XXL-JOB相关面试题

分布式任务调度-xxl-job 任务量大&#xff0c;分片执行 定义cron表达式灵活 定时任务失败了&#xff0c;重试和统计 xxl-job路由策略有哪些&#xff1f; 轮询 故障转移 分片广播:**广播触发对应的集群中所有机器执行一次任务,同时系统自动传递分片参数,**可以根据分片参数开发…

华东师范大学数学分析第五版PDF习题答案上册及下册

“数学分析”是数学专业最重要的一门基础课程&#xff0c;也是报考数学类专业硕士研究生的专业考试科目。为了帮助、指导广大读者学好这门课程&#xff0c;编者编写了与华东师范大学数学科学学院主编的《数学分析》(第五版)配套的辅导用书&#xff0c;以帮助读者加深对基本概念…

MATLAB实现GARCH(广义自回归条件异方差)模型计算VaR(Value at Risk)

MATLAB实现GARCH(广义自回归条件异方差)模型计算VaR(Value at Risk) 1.计算模型介绍 使用GARCH&#xff08;广义自回归条件异方差&#xff09;模型计算VaR&#xff08;风险价值&#xff09;时&#xff0c;方差法是一个常用的方法。GARCH模型能够捕捉到金融时间序列数据中的波…

基于YOLOv8深度学习的智慧课堂学生专注度检测系统(PyQt5界面+数据集+训练代码)

本研究提出了一种基于YOLOv8深度学习的智慧课堂学生专注度检测系统&#xff0c;旨在实现对课堂中学生专注度的实时分析与评估。随着智慧教育的快速发展&#xff0c;学生的课堂表现和专注度成为评估学习效果的重要因素之一。然而&#xff0c;传统的专注度评估方法往往依赖于主观…

如何在 Ubuntu 上安装 Emby 媒体服务器

Emby 是一个开源的媒体服务器解决方案&#xff0c;它能让你整理、流媒体播放和分享你的个人媒体收藏&#xff0c;包括电影、音乐、电视节目和照片。Emby 帮你集中多媒体内容&#xff0c;让你无论在家还是在外都能轻松访问。它还支持转码&#xff0c;让你能够播放各种格式的内容…

HarmonyOS 如何获取设备信息(系统、版本、网络连接状态)

文章目录 前言一、引入模块和基本设备信息的获取二、设备硬件和系统版本信息的获取三、获取安全相关的设备信息四、获取网络状态信息五、完整 Demo 代码1. 导入所需模块2. 获取设备基本信息代码解析 3. 检测网络连接状态4. 执行函数 总结 前言 HarmonyOS 提供了一个强大的 API…

ES6笔记

ES6 ECMAScript ECMA组织&#xff1a;脚本语言标准化国际组织 1.什么是ES6 ES的全称是&#xff1a;ECMAScript&#xff0c;它是ECMA国际标准化组织制定的一项脚本语言的标准规范 2015年6月&#xff1a;ES2015 2016年6月&#xff1a;ES2016 2017年6月&#xff1a;ES2017 2018年…

常用命令之LinuxOracleHivePython

1. 用户改密 passwd app_adm chage -l app_adm passwd -x 90 app_adm -> 执行操作后&#xff0c;app_adm用户的密码时间改为90天有效期--查看该euser用户过期信息使用chage命令 --chage的参数包括 ---m 密码可更改的最小天数。为零时代表任何时候都可以更改密码。 ---M 密码…

游戏如何应对内存修改

据观察&#xff0c;近年来游戏黑灰产攻击角度多样化趋势显著&#xff0c;主要面临工作室、定制注入挂、模拟点击挂、内存修改挂、破解版等多方面安全问题。 据FairGuard数据统计&#xff0c;在游戏面临的众多安全风险中&#xff0c;「内存修改」攻击占比约为13%&#xff0c;主…