Linux内核4.14版本——drm框架分析(1)——drm简介

news2024/11/24 23:05:52

目录

1. DRM简介(Direct Rendering Manager)

1.1 DRM发展历史

1.2 DRM架构对比FB架构优势

 1.3 DRM图形显示框架

 1.4 DRM图形显示框架涉及元素

1.4.1 DRM Framebuffer

1.4.2 CRTC

1.4.3 Encoder

1.4.4 Connector

1.4.5 Bridge

1.4.6 Panel

1.4.7 Fence

1.4.8 Plane

1.4.9 小结

2. DRM驱动框架

2.1 DRM驱动对象介绍

2.2 DRM抽象硬件如何关联DRM Object

 3. DRM简单示例

3.1 打开DRM设备文件

 3.2 获取显卡资源句柄

3.3  获取connectorId

3.4 创建FrameBuffer

3.5 设置Crtc模式

3.6 资源清理工作

4. libdrm安装

5. 本章小结

6. 参考文件


1. DRM简介(Direct Rendering Manager)

        传统linux显示设备驱动开发时,通常使用FB驱动架构,随着显卡性能升级:显示覆盖(菜单层级)、GPU加速、硬件光标,传统FB架构无法很好支持,此外,对于多应用的访问冲突也无法很好控制。在这样的背景下,DRM应用而生。

        DRM是linux内核中负责与显卡交互的管理架构,用户空间很方便的利用DRM提供的API,实现3D渲染、视频解码和GPU计算等工作。

1.1 DRM发展历史

        (1)1999年,Precision Insight公司首次为 XFree86 4.0 Server 开发 DRI 显示框架,用于更好的适配 3DFX 公司显卡,初版DRM代码产出后,接下来的几年时间里,DRM 所支持的显卡列表不断被扩充。

        (2)2008年10月,Linux kernel 2.6.27 进行了一次重大的源码重组:DRM 的整套源码被放到了/drivers/gpu/drm/目录下,不同的GPU厂商代码也被放到了各自子目录下。

        (3)2014年6月,Atomic API 被添加到Linux 3.16,许多驱动也都转而使用这些新的 API。

        (4)2018年,又有10个基于 atomic 框架的 DRM 新增驱动被添加到Linux kernel。

1.2 DRM架构对比FB架构优势

        DRM是目前Linux的主流图形显示框架,相比于传统FB架构,DRM允许多个程序同时使用视频硬件资源,管理多个程序的资源请求、访问,综上所述DRM更能适应日益更新的显示硬件,DRM优势主要体现:

       (1)DRM原生支持多图层合成,FB原生不支持多层合成。

       (2)FB不支持VSYNC、DMA-BUF、异步更新和fence机制,但DRM原生都支持。

       (3)DRM统一管理GPU和Display驱动,让软件升级、维护和管理更加方便。

 1.3 DRM图形显示框架

        DRM检测到的每个GPU都作为DRM设备,并为之创建一个设备文件/dev/dri/cardX与之连接,从整体架构上来看主要分为3个主要部分:

       (1)libdrm (接口库)

        对底层接口进行封装,向上层提供通用的API接口,主要是对各种IOCTL接口进行封装,便于重用与代码共享。

      (2)KMS (Kernel Mode Setting)

        正常工作时,需要设置显卡或者图形适配器的模式,主要体现在以下两个方面:

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

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

      (3)GEM (Graphics Execution Manager)

       提供内存管理方法,主要负责显示buffer的分配和释放。

DRM图形显示框架总览

 1.4 DRM图形显示框架涉及元素

        本章节介绍DRM框架中的一些重点模块的功能与在显示链路中的作用,下图为APP调用DRM到屏幕显示的流程框图。

         下表对DRM中KMS和GEM两个模型的不同组件进行概述性说明,辅以高通平台代码层级的对应关系说明,以加深架构与流程之间的对应联系。

各部分说明:

1.4.1 DRM Framebuffer

        是一块内存区域,可以理解为一块画布,驱动和应用层都能访问它。绘制前需要将它格式化,设定绘制的色彩模式(例如RGB24,YUV 等)和画布的大小(分辨率),不负责显存的分配释放。

1.4.2 CRTC

       阴极摄像管上下文(显示控制器),也可以理解为扫描仪(对显示buffer进行扫描,并产生时序信号(RGB timing)的硬件模块)。CRTC对内连接 Framebuffer 地址,对外连接 Encoder,会扫描 Framebuffer 上的内容,叠加上 Planes 的内容,最后传给Encoder。在 rockchip 平台是 SOC 内部 VOP(部分文档也称为 LCDC)模块的抽象。如图:

0452b6c900ab4c5095cae5e0cbdd67ba.png

83b9ae47158b4486803adc807a9d6f16.png

 注:crtc代码层面的作用:

        1)DPMS (Display Power Manage System) 电源状态管理 (crtc_funcs->dpms)。

        2)将 Framebuffer 转换成标准的 LCDC Timing ,其实就是一帧图像刷新的过程(crtc_funs->mode_set)。

       3)帧切换,即在 VBlank 消影期间,切换 Framebuffer(crtc_funcs->page_flip)。

       4)gamma校正值调整(crtc_funcs->gamma_set)。

1.4.3 Encoder

        编码器/输出转换器,负责将CRTC输出的timing时序转换成外部设备所需要的信号的模块。它的作用就是将内存的 pixel 像素编码(转换)为显示器所需要的信号(因为画面显示到不同的设备(Display Device)上,需要将画面转化为不同的电信号)。如指 RGB、LVDS、DSI、eDP、HDMI、CVBS、VGA 等显示接口。另外 Encoder 和 CRTC 之间的交互就是我们所说的 ModeSetting,其中包含了前面提到的色彩模式、还有时序(Timing)等。

注:Encoder代码层面的作用:

        1)DPMS (Display Power Manage System) 电源状态管理 (encoder_funcs->dpms)

        2)将 VOP 输出的 lcdc Timing 打包转化为对应接口时序 HDMI TMDS / … (encoder_funcs->mode_set)

1.4.4 Connector

        连接器,指 encoder 和 panel 之间交互的接口部分。对应于物理连接器 (例如 VGA, DVI, FPD-Link, HDMI, DisplayPort, S-Video等) ,它不是指物理线,在 DRM中,Connector 是一个抽象的数据结构,代表连接的显示设备,从Connector中可以得到当前物理连接的输出设备相关的信息。

注:Connector代码层面的作用

        1)获取上报 热拔插 Hotplug 状态

        2)读取并解析屏 (Panel) 的 EDID 信息

1.4.5 Bridge

        桥接设备,一般用于注册 encoder 后面另外再接的转换芯片,如 DSI2HDMI 转换芯片。桥接ic所处位置,如图:

2e32dc90c57a459293dd91ea5d235943.png

1.4.6 Panel

        泛指屏,各种LCD, HDMI等显示设备的抽象。用于获取LCD mode参数,并提供LCD休眠唤醒的回调接口,供encoder调用。

1.4.7 Fence

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

1.4.8 Plane

        硬件图层, 和 Framebuffer 一样是内存地址。在 rockchip 平台是 SOC 内部 VOP(LCDC)模块 win 图层的抽象。一个Plane代表一个image layer, 最终的image由一个或者多个Planes组成。

plane的主要类型:

DRM_PLANE_TYPE_PRIMARY:主要图层,通常用于仅支持RGB格式的简单图层

DRM_PLANE_TYPE_OVERLAY:叠加图层,通常用于YUV格式的视频图层

DRM_PLANE_TYPE_CURSOR:光标图层,一般用于pc系统,用于显示鼠标

1.4.9 小结

实例解析下 CRTC / Encoder / Connector 的行为:

         1)首先 HDMI 驱动检测到电视 Plugin 信号,读出电视的 EDID 信号,获取电视的分辨率信息 (DRM Connector)。

        2)Userspace 将需要显示的数据填充在 framebuffer 里面,然后通过 libdrm 接口通知 VOP 设备开始显示。

        3)接着 VOP 驱动将 framebuffer 里面的数据转换成标准的 LCDC Timing 时序 (DRM CRTC)。

        4)同时 HDMI 驱动将 HDMI 硬件模块的 LCDC 时序配置与 VOP 输出时序一致,准备将输入的 LCDC Timing 转化为电视识别的 HDMI TMDS 信号 (DRM Encoder)。

名词解释:

        DRI:Direct Rendering Infrastructure,直接访问硬件接口

        EDID:Extended Display Identification Data,扩展显示标识数据,共有128字节。其中包含有关显示器及其性能的参数,包括供应商信息、最大图像大小、颜色设置、厂商预设置、频率范围的限制以及显示器名和序列号的字符串。

        DDC:Display Data Channel,显示数据通道,顾名思义,它是一个通道,DDC是用来传送EDID信息的。EDID信息包含了显示器需要的128字节,128个字节的附加块可以存储在初始的EDID块之后的EDID扩展块VDIF,这些块包含addtional具体的时序信息。

2. DRM驱动框架

2.1 DRM驱动对象介绍

        DRM内部的Objects是组成DRM框架的核心,下图中蓝色部分为物理硬件的抽象,棕色部分则为软件的抽象,其中GEM结构体为:drm_gem_object,其余部分位于结构体drm_mode_object中.

        PS:drm_panel不属于object范畴,只是为了降低LCD驱动与encoder驱动间的耦合,是一堆回调函数集合。

         如图所属,drm将显示部分抽象出了framebuffer、plane、crtc、encoder、connector五部分。

        (1)在同一时刻,一个framebuffer与一个plane动态绑定。

        (2)在同一时刻,通常一个或多个plane与一个crtc静态绑定。

        (3)在同一时刻,一个crtc与多个encoder动态绑定。

        (4)在同一时刻,通常一个encoder与一个connector静态绑定。

2.2 DRM抽象硬件如何关联DRM Object

        DRM的objects并不难理解,重要的是如何将实际的硬件与这些object进行关联,下面会以MIPI DSI接口为例进行介绍软件架构与DRM object的对应关系。

 

 其中组件说明:

 3. DRM简单示例

        DRM代码非常庞大,显卡逻辑也非常复杂,在学习DRM架构时,需要通过实践对DRM的流程进行理解,以达到事半功倍的效果。

        下面会以模式设置案例,对DRM架构的流程进行解析。modeset主要流程如下:

图3.1 DRM Modeset流程总览

3.1 打开DRM设备文件

         DRM框架成功加载后,会创建一个设备文件/dev/dri/card0,上层用户应用可以通过该文件节点,获取显卡的各种操作。

 3.2 获取显卡资源句柄

       打开DRM设备文件后,通过以下函数获取显卡的资源句柄,进而进行显卡资源的操作。

3.3  获取connectorId

        获取了drmModeRes后,获取它的连接对象。

3.4 创建FrameBuffer

        创建FrameBuffer后,然后映射一片内存,对这块内存进行像素数据填充.

3.5 设置Crtc模式

         FB创建成功并进行清0操作,可以在里面填充任何数据,然后设置CRTC后,FB的内容就可以显示在屏幕。

        CRTC模式设置函数:drmModeSetCrtc(),参数为:fd、crtc句柄、FB句柄、X\Y坐标等。

3.6 资源清理工作

        显示完成后,GUI会一直运行,一般不必实施资源清理工作。

4. libdrm安装

 libdrm下载链接:Index of /libdrm

参考:LIBDRM使用_linux_dafei的博客-CSDN博客

5. 本章小结

        本文介绍了DRM架构的发展历史、驱动框架以及简单示例,旨在帮助读者了解DRM架构的形成、功能流程实现,DRM代码庞大且复杂,想要深入理解它的内涵,最好的办法就是根据实际需求来进行代码流程梳理,后续章节也会对该部分进行展开讲解。

         此外,DRM架构符合功能日益强大的现代显示设备,但仍有很多老的设备以及软件需要FB支持,在目前DRM框架中,会存在模拟FB设备的代码,参见drivers/gpu/drm/xxx/drv.c文件,会在设备目录下出现:/dev/fb0 。

6. 参考文件

7. DRM图形显示框架 — [野火]嵌入式Linux驱动开发实战指南——基于STM32MP157开发板 文档

深入讲解DRM架构介绍(一)_Linux内核站的博客-CSDN博客_drm框架

Android 图形系统(3)---- DRM 显示框架初步 - 简书

linux驱动系列学习之DRM(十)-易微帮

LCD DRM驱动框架分析一_drmmodesetcrtc_沉沦者的博客-CSDN博客

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

双指针法将时间复杂度从 O(n^2) 优化到 O(n)

[1] 什么是双指针法 双指针法(Two Pointers)是一种常见的算法技巧,常用于数组和链表等数据结构中。 双指针法的基本思想是维护两个指针,分别指向不同的位置,通过它们的移动来解决问题。在某些情况下,使用双…

【Leetcode】移除链表元素 链表的中间节点 链表中倒数第k个节点

目录 一.【Leetcode203】移除链表元素 1.链接 2.题目再现 A.双指针法 B.类尾删法 C.哨兵位 二.【Leetcode876】链表的中间节点 1.链接:链表的中间节点 2.题目再现 3.解法:快慢指针 三.链表中倒数第k个节点 1.链接:链表中倒数第k个…

LiveGBS国标GB/T28181国标视频流媒体平台-功能报警订阅配置报警预案告警截图及录像

LiveGBS国标GB/T28181国标视频流媒体平台-功能报警订阅配置报警预案告警截图及录像1、报警信息1.1、报警查询1.2、配置开启报警订阅1.2.1、国标设备编辑1.2.2、选择开启报警订阅1.3、配置摄像头报警1.3.1、配置摄像头报警通道ID1.3.2、配置摄像头开启侦测1.3.3、尝试触发摄像头…

企业为什么需要做APP安全评估?

近几年新型信息基础设施建设和移动互联网技术的不断发展,移动APP数量也呈现爆发式增长,进而APP自身的“脆弱性”也日益彰显,这对移动用户的个人信息及财产安全带来巨大威胁和挑战。在此背景下,国家出台了多部法律法规,…

【架构师】跟我一起学架构——微服务分层监控

博客昵称:架构师Cool 最喜欢的座右铭:一以贯之的努力,不得懈怠的人生。 作者简介:一名Coder,软件设计师/鸿蒙高级工程师认证,在备战高级架构师/系统分析师,欢迎关注小弟! 博主小留言…

机器学习与目标检测作业:安装pytorch

机器学习与目标检测作业:安装pytorch一、 进入官网复制下载命令二、 下载的过程2.1 conda命令运行三、 测试pytorch是否安装成功安装pytorch教程 一、 进入官网复制下载命令 进入官网复制下载命令如下图所示 二、 下载的过程 下载的过程如下图所示 2.1 conda命令运…

vue3中引入初始化样式

1、创建一个reset.css文件 2、文件内容为: css charset “utf-8”;html{background-color:#fff;color:#000;font-size:12px} body,ul,ol,dl,dd,h1,h2,h3,h4,h5,h6,figure,form,fieldset,legend,input,textarea,button,p,blockquote,th,td,pre,xmp{margin:0;padding…

华为机试题:HJ100 等差数列(python)

文章目录(1)题目描述(2)Python3实现(3)知识点详解1、input():获取控制台(任意形式)的输入。输出均为字符串类型。1.1、input() 与 list(input()) 的区别、及其相互转换方…

芯驰(E3-gateway)开发板环境搭建以及调试遇到问题的解决

1-Windows下环境配置 可以在Windows上使用命令行或者IAR IDE编译SSDK项目。Windows编译依赖的工具已经包含在 prebuilts/windows 目录中,包括编译器、Python和命令行工具。 1.1.1 CMD SSDK集成 msys 工具,可以在Windows命令行中完成SDK的配置、编译和…

零入门kubernetes网络实战-19->golang编程netlink包方式操作tun设备

《零入门kubernetes网络实战》视频专栏地址 https://www.ixigua.com/7193641905282875942 本篇文章视频地址(稍后上传) 本篇文章介绍一下,使用 github.com/vishvananda/netlink 来操作tun设备 1、安装github.com/vishvananda/netlink go get github.com/vishvanan…

Java的Groovy执行器内存泄露(MetaSpace)问题分析与解决办法

环境与背景 在java程序中通过GroovyScriptEvaluator执行器创建脚本Script对象调用Groovy脚本语言来完成某些功能, ,会通过AppClassLoader或者GroovyClassLoader去生产一个随机的名称的Groovy的Script类对象,导致元数据,产生的class类会被AppClassLoader或者GroovyClassLoader内…

软件测试必备知识

一、软件测试的基本概念①需求IEEE规定:软件需求是(1)用户解决问题或达到目标所需 条件或权能。(2)系统或系统部件要满足合同、标准、规范或其他正式规定文档所需具有的条件或权能。一种反应上面(1&#xf…

MyBatisPlus 批量添加

文章目录现状优化效果现状 一般来说,批量插入可以使用 MyBatisPlus 中 ServiceImpl 自带的方法 saveBatch 打开 sql 日志,application.yml 添加配置,mapper-locations 配置 mapper 路径 mybatis-plus:configuration:log-impl: org.apache.i…

LEAP模型的能源环境发展、碳排放建模预测及不确定性分析

LEAP(Long Range Energy Alternatives Planning System/ Low emission analysis platform,长期能源可替代规划模型)是一种自下而上的能源-环境核算工具,由斯德哥尔摩环境研究所和美国波士顿大学联合研发。该模型与情景分析法紧密结…

基于Jetson Tx2 Nx的Qt、树莓派等ARM64架构的Ptorch及torchvision的安装

前提 已经安装好了python、pip及最基本的依赖库 若未安装好点击python及pip安装请参考这篇博文 https://blog.csdn.net/m0_51683386/article/details/129320492?spm1001.2014.3001.5502 特别提醒 一定要先根据自己板子情况,找好python、torch、torchvision的安…

信箱|邮箱系统

技术:Java、JSP等摘要:在经济全球化和信息技术飞速发展的今天,通过邮件收发进行信息传递已经成为主流。目前,基于B/S(Browser/Server)模式的MIS(Management information system)日益…

C语言数组二维数组

C 语言支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合。数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量。 数组的声明并不是声明一个个单独的变量,比如 runoob0、runoob1、…、runoob99,而是…

唤醒手腕前端 Electron Gui 桌面应用开发详细教程(流程模型、进程通信、进程沙盒化)

流程模型 Electron 继承了来自 Chromium 的多进程架构,这使得此框架在架构上非常相似于一个现代的网页浏览器。 为什么不是一个单一的进程? 网页浏览器是个极其复杂的应用程序。 除了显示网页内容的主要能力之外,他们还有许多次要的职责&a…

红黑树(Insert())

文章目录红黑树代码红黑树性质红黑树vsAVL树红黑树的实现Insert()情况一:如果我插入的新节点时红色的情况二:叔叔是黑色或者不存在情况三: cur红,p为红,g为黑,u不存在或者为黑-双旋检查erase()红黑树vsAVL树红黑树的应用:红黑树 二叉搜索树 …

分布式框架RabbitMQ详解以及编程特性Base实现

消息队列MQ MQ的主要作用有: 异步 例子: 快递员发快递,直接到客户家效率会很低。引入菜鸟驿站后,快递员只需要把快递放到菜鸟驿站,就可以继续发其他快递去了。客户再按自己的时间安排去菜鸟驿站取快递. 作用:异步能提高系统的…