简介¶
Linux DRM 层包含旨在支持复杂图形设备需求的代码,这些设备通常包含非常适合 3D 图形加速的可编程流水线。 内核中的图形驱动程序可以使用 DRM 函数来简化内存管理、中断处理和 DMA 等任务,并为应用程序提供统一的接口。
关于版本说明:本指南涵盖 DRM 树中发现的功能,包括 TTM 内存管理器、输出配置和模式设置,以及新的 vblank 内部结构,以及当前内核中发现的所有常规功能。
[在此处插入典型 DRM 堆栈的图表]
风格指南¶
为了保持一致性,本文档使用美式英语。 缩写以全部大写字母书写,例如:DRM、KMS、IOCTL、CRTC 等。 为了方便阅读,文档充分利用 kerneldoc 提供的标记字符:@parameter 用于函数参数,@member 用于结构成员(在同一结构内),&struct 结构用于引用结构,function() 用于函数。 如果被引用对象的 kerneldoc 存在,这些都会自动超链接。 引用函数 vtable 中的条目(以及一般的结构成员)时,请使用 &vtable_name.vfunc。 遗憾的是,这尚未产生指向成员的直接链接,仅指向结构。
除非在特殊情况下(将锁定变体与未锁定变体分开),否则函数的锁定要求不会记录在 kerneldoc 中。 相反,应使用例如 WARN_ON(!mutex_is_locked(...));
在运行时检查锁定。 由于忽略文档比忽略运行时噪音更容易,因此这提供了更大的价值。 最重要的是,运行时检查确实需要在锁定规则更改时进行更新,从而增加了它们正确的机会。 在文档中,锁定规则应在相关结构中解释:要么在锁的注释中解释它保护的内容,要么数据字段需要一个关于哪个锁保护它们的注释,或者两者都需要。
具有非 void
返回值的函数应具有一个名为“Returns”的部分,解释不同情况下预期的返回值及其含义。 目前,对于该部分名称是否应全部大写,以及是否应以冒号结尾,尚未达成共识。 请使用文件本地样式。 其他常见的章节名称是“Notes”,其中包含危险或棘手的角落情况的信息,以及“FIXME”,其中可以清理接口。
另请阅读内核文档的总体指南。
kAPI 的文档要求¶
所有导出到其他模块的内核 API 都必须记录在案,包括其数据结构,以及至少一个简短的介绍性部分,解释总体概念。 文档应尽可能多地以 kerneldoc 注释的形式放入代码本身中。
不要盲目地记录所有内容,而只记录与驱动程序作者相关的内容:drm.ko 的内部函数以及绝对的静态函数不应具有正式的 kerneldoc 注释。 如果您认为有必要添加注释,请使用普通的 C 注释。 您可以在注释中使用 kerneldoc 语法,但它不应以 /** kerneldoc 标记开头。 对于数据结构,请按照文档指南,使用 /* private: */
注释来注释任何完全私有的内容。
入门¶
欢迎有兴趣帮助 DRM 子系统的开发人员。 通常,人们会选择提交针对 checkpatch 或 sparse 报告的各种问题的补丁。 我们欢迎此类贡献。
任何想要更上一层楼的人都可以在TODO 列表上找到一份管理任务清单。
贡献流程¶
大多数情况下,DRM 子系统的运作方式与任何其他内核子系统类似,有关其运作方式,请参阅主要流程指南和文档。 在这里,我们只记录 GPU 子系统的一些特殊性。
功能合并截止日期¶
所有功能工作都必须在当前发布周期的 -rc6 版本之前进入 linux-next 树,否则必须推迟,并且无法进入下一个合并窗口。 所有补丁都必须在 -rc7 之前最新到达 drm-next 树,但如果您的分支不在 linux-next 中,则必须已经在 -rc6 之前完成。
在此之后,只允许修复错误(就像上游合并窗口以 -rc1 版本关闭之后一样)。 不允许启用新平台或添加新驱动程序。
这意味着大约有一个月的功能工作无法合并的停机期。 建议的处理方法是拥有一个始终打开的 -next 树,但要确保在停机期间不要将其馈送到 linux-next 中。 例如,drm-misc 就是这样运作的。
行为准则¶
作为 freedesktop.org 项目,dri-devel 和 DRM 社区都遵守贡献者盟约,可在以下网址找到:https://www.freedesktop.org/wiki/CodeOfConduct
与邮件列表、IRC 或错误跟踪器上的社区成员互动时,请以尊重和文明的方式行事。 社区代表整个项目,项目不容忍辱骂或欺凌行为。
用作示例的简单 DRM 驱动程序¶
DRM 子系统包含许多辅助函数,可简化简单图形设备的驱动程序编写。 例如,drivers/gpu/drm/tiny/ 目录包含一组驱动程序,这些驱动程序足够简单,可以在单个源文件中实现。
这些驱动程序使用struct drm_simple_display_pipe_funcs
,它隐藏了 DRM 子系统的任何复杂性,只需要驱动程序实现一些操作设备所需的函数。 这可以用于只需要一个显示管道,其中一个全屏扫描输出缓冲区馈送一个输出的设备。
微型 DRM 驱动程序是了解 DRM 驱动程序应如何设计的良好示例。 由于只有数百行代码,因此非常容易阅读。
外部参考¶
第一次深入研究 Linux 内核子系统可能是一种令人不知所措的体验,人们需要熟悉所有概念并了解子系统的内部结构以及其他细节。
为了缩短学习曲线,本节包含一个演示文稿和文档列表,可用于了解 DRM/KMS 和一般图形。
人们可能出于不同的原因而想要进入 DRM:移植现有的 fbdev 驱动程序、为新硬件编写 DRM 驱动程序、修复在图形用户空间堆栈上工作时可能面临的错误等。为此,学习材料涵盖了 Linux 图形堆栈的许多方面。 从内核和用户空间堆栈的概述到非常具体的主题。
该列表按时间倒序排序,以将最新的材料保持在顶部。 但所有这些都包含有用的信息,并且遍历旧材料以了解 DRM 子系统更改的理由和背景可能很有价值。
会议演讲¶
Linux 和用户空间图形堆栈概述 - Paul Kocialkowski (2020)
在 Linux 上将像素显示在屏幕上:内核模式设置简介 - Simon Ser (2020)
关于上游图形的一切 - Simona Vetter (2019)
Linux DRM 子系统简介 - Maxime Ripard (2017)
拥抱原子(显示)时代 - Simona Vetter (2016)
原子 KMS 驱动程序的解剖 - Laurent Pinchart (2015)
驱动程序的原子模式设置 - Simona Vetter (2015)
嵌入式 KMS 驱动程序的解剖 - Laurent Pinchart (2013)
幻灯片和文章¶
简而言之的 Linux 图形堆栈,第 1 部分 - Thomas Zimmermann (2023)
简而言之的 Linux 图形堆栈,第 2 部分 - Thomas Zimmermann (2023)
了解 Linux 图形堆栈 - Bootlin (2022)
DRM KMS 概述 - STMicroelectronics (2021)
Linux 图形堆栈 - Nathan Gauër (2017)
原子模式设置设计概述,第 1 部分 - Simona Vetter (2015)
原子模式设置设计概述,第 2 部分 - Simona Vetter (2015)
从新手的角度看 DRM/KMS 子系统 - Boris Brezillon (2014)
Linux 图形堆栈简介 - Iago Toral (2014)
Linux 图形堆栈 - Jasper St. Pierre (2012)