Direkter Rendering-Manager - Direct Rendering Manager

Direkter Rendering-Manager
Originalautor(en) kernel.org & freedesktop.org
Entwickler kernel.org & freedesktop.org
Geschrieben in C
Typ
Lizenz
Webseite dri .freedesktop .org /wiki /DRM

Der Direct Rendering Manager ( DRM ) ist ein Subsystem des Linux-Kernels, das für die Schnittstellen zu GPUs moderner Grafikkarten verantwortlich ist . DRM stellt eine API bereit , die User-Space- Programme verwenden können, um Befehle und Daten an die GPU zu senden und Vorgänge wie das Konfigurieren der Moduseinstellung der Anzeige durchzuführen . DRM wurde zuerst als Kernel-Space- Komponente der X Server Direct Rendering Infrastructure entwickelt , wird aber seitdem von anderen Grafik-Stack-Alternativen wie Wayland verwendet .

User-Space-Programme können die DRM-API verwenden, um der GPU zu befehlen, hardwarebeschleunigtes 3D-Rendering und Videodekodierung sowie GPGPU-Computing durchzuführen .

Überblick

Der Linux-Kernel hatte bereits eine API namens fbdev , die verwendet wurde, um den Framebuffer einer Grafikkarte zu verwalten , aber sie konnte nicht verwendet werden, um die Anforderungen moderner 3D-beschleunigter GPU- basierter Videohardware zu erfüllen . Diese Geräte erfordern normalerweise das Einstellen und Verwalten einer Befehlswarteschlange in ihrem eigenen Speicher , um Befehle an die GPU zu senden, und erfordern auch die Verwaltung von Puffern und freiem Speicherplatz in diesem Speicher. Anfänglich verwalteten User-Space-Programme (wie der X Server ) diese Ressourcen direkt, aber sie taten normalerweise so, als ob sie die einzigen wären, die darauf Zugriff hätten. Wenn zwei oder mehr Programme gleichzeitig versuchten, dieselbe Hardware zu steuern und ihre Ressourcen jedes auf seine eigene Weise einzustellen, endeten sie meistens katastrophal.

Zugriff auf Grafikkarte ohne DRM
Ohne DRM
Zugriff auf Grafikkarte mit DRM
Mit DRM
DRM ermöglicht mehreren Programmen gleichzeitigen Zugriff auf die 3D-Grafikkarte, wodurch Kollisionen vermieden werden

Der Direct Rendering Manager wurde erstellt, um mehreren Programmen die gemeinsame Nutzung von Videohardwareressourcen zu ermöglichen. Der DRM erhält exklusiven Zugriff auf die GPU und ist für die Initialisierung und Wartung der Befehlswarteschlange, des Speichers und aller anderen Hardwareressourcen verantwortlich. Programme, die die GPU verwenden möchten, senden Anfragen an DRM, das als Vermittler fungiert und darauf achtet, mögliche Konflikte zu vermeiden.

Der Umfang von DRM wurde im Laufe der Jahre erweitert, um mehr Funktionen abzudecken, die zuvor von User-Space-Programmen verwaltet wurden, wie z. B. Framebuffer-Verwaltung und Moduseinstellung , Speicherfreigabeobjekte und Speichersynchronisierung. Einige dieser Erweiterungen erhielten spezifische Namen, wie beispielsweise Graphics Execution Manager (GEM) oder Kernel Mode Setting (KMS), und die Terminologie setzt sich durch, wenn die von ihnen bereitgestellte Funktionalität ausdrücklich erwähnt wird. Aber sie sind wirklich Teile des gesamten Kernel-DRM-Subsystems.

Der Trend, zwei GPUs in einen Computer zu integrieren – eine separate GPU und eine integrierte – führte zu neuen Problemen wie der GPU-Umschaltung , die ebenfalls auf der DRM-Ebene gelöst werden mussten. Um der Nvidia Optimus- Technologie gerecht zu werden, wurde DRM mit GPU-Offloading-Fähigkeiten namens PRIME ausgestattet.

Softwarearchitektur

Ein Prozess, der den Direct Rendering Manager des Linux-Kernels verwendet, um auf eine 3D-beschleunigte Grafikkarte zuzugreifen

Der Direct Rendering Manager befindet sich im Kernel-Space , daher müssen User-Space-Programme Kernel -Systemaufrufe verwenden , um seine Dienste anzufordern. DRM definiert jedoch keine eigenen benutzerdefinierten Systemaufrufe. Stattdessen folgt es dem Unix- Prinzip " Alles ist eine Datei ", um die GPUs über den Dateisystem-Namensraum bereitzustellen, indem Gerätedateien unter der /devHierarchie verwendet werden. Jede von DRM erkannte GPU wird als DRM-Gerät bezeichnet und es wird eine Gerätedatei (wobei X eine fortlaufende Nummer ist) erstellt, um eine Verbindung zu ihr herzustellen. User-Space-Programme, die mit der GPU kommunizieren möchten, müssen diese Datei öffnen und ioctl- Aufrufe verwenden, um mit DRM zu kommunizieren. Unterschiedliche ioctls entsprechen unterschiedlichen Funktionen der DRM- API . /dev/dri/cardX

Eine Bibliothek namens libdrm wurde erstellt, um die Schnittstelle von Userspace-Programmen mit dem DRM-Subsystem zu erleichtern. Diese Bibliothek ist lediglich ein Wrapper , der für jedes ioctl der DRM-API eine in C geschriebene Funktion sowie Konstanten, Strukturen und andere Hilfselemente bereitstellt. Die Verwendung von libdrm vermeidet nicht nur die direkte Offenlegung der Kernel-Schnittstelle für Anwendungen, sondern bietet auch die üblichen Vorteile der Wiederverwendung und gemeinsamen Nutzung von Code zwischen Programmen.

Details zur Architektur des Direct Rendering Manager: DRM-Kern und DRM-Treiber (einschließlich GEM und KMS) mit Schnittstellen von libdrm

DRM besteht aus zwei Teilen: einem generischen „DRM-Kern“ und einem spezifischen („DRM-Treiber“) für jeden unterstützten Hardwaretyp. Der DRM-Kern bietet das grundlegende Framework, in dem sich verschiedene DRM-Treiber registrieren können, und bietet dem Benutzerbereich auch einen minimalen Satz von ioctls mit gemeinsamer, hardwareunabhängiger Funktionalität. Ein DRM-Treiber hingegen implementiert den hardwareabhängigen Teil der API, der für den unterstützten GPU-Typ spezifisch ist. Es sollte die Implementierung der verbleibenden ioctls bereitstellen, die nicht vom DRM-Kern abgedeckt werden, aber es kann auch die API erweitern und zusätzliche ioctls mit zusätzlichen Funktionen anbieten, die nur auf solcher Hardware verfügbar sind. Wenn ein bestimmter DRM-Treiber eine erweiterte API bereitstellt, wird User-Space libdrm auch um eine zusätzliche Bibliothek libdrm- driver erweitert , die vom User-Space als Schnittstelle zu den zusätzlichen ioctls verwendet werden kann.

API

Der DRM-Kern exportiert mehrere Schnittstellen zu User-Space-Anwendungen, die im Allgemeinen durch entsprechende libdrmWrapper-Funktionen verwendet werden sollen. Darüber hinaus exportieren Treiber gerätespezifische Schnittstellen zur Verwendung durch User-Space-Treiber und geräteabhängige Anwendungen über ioctls- und sysfs- Dateien. Zu den externen Schnittstellen gehören: Speicherzuordnung, Kontextverwaltung, DMA- Operationen, AGP- Verwaltung, vblank- Steuerung, Fencing- Verwaltung, Speicherverwaltung und Ausgabeverwaltung.

DRM-Master und DRM-Auth

Es gibt mehrere Operationen (ioctls) in der DRM-API, die entweder aus Sicherheitsgründen oder aus Gründen der Parallelität auf die Verwendung durch einen einzelnen User-Space-Prozess pro Gerät beschränkt werden müssen. Um diese Einschränkung zu implementieren, beschränkt DRM, dass solche ioctls nur von dem Prozess aufgerufen werden, der als "Master" eines DRM-Geräts betrachtet wird, normalerweise als DRM-Master bezeichnet . Nur bei einem von allen Prozessen, bei denen der Geräteknoten geöffnet ist, wird sein Datei-Handle als Master markiert, insbesondere der erste, der das SET_MASTER- ioctl aufruft. Jeder Versuch, eines dieser eingeschränkten ioctls zu verwenden, ohne der DRM-Master zu sein, führt zu einem Fehler. Ein Prozess kann seine Master-Rolle auch aufgeben – und einen anderen Prozess übernehmen lassen – indem er das DROP_MASTER- ioctl aufruft. /dev/dri/cardX

Der X-Server – oder jeder andere Anzeigeserver – ist normalerweise der Prozess, der den DRM-Master-Status in jedem von ihm verwalteten DRM-Gerät erhält, normalerweise wenn er den entsprechenden Geräteknoten während seines Starts öffnet, und behält diese Berechtigungen für die gesamte grafische Sitzung bei, bis es endet oder stirbt.

Für die verbleibenden User-Space-Prozesse gibt es eine andere Möglichkeit, die Berechtigung zum Aufrufen einiger eingeschränkter Operationen auf dem DRM-Gerät namens DRM-Auth zu erhalten . Es ist im Grunde eine Methode der Authentifizierung gegenüber dem DRM-Gerät, um ihm zu beweisen, dass der Prozess die Zustimmung des DRM-Masters hat, solche Privilegien zu erhalten. Das Verfahren besteht aus:

  • Der Client erhält ein eindeutiges Token – eine 32-Bit-Ganzzahl – vom DRM-Gerät mithilfe von GET_MAGIC ioctl und übergibt es auf beliebige Weise an den DRM-Master-Prozess (normalerweise eine Art IPC ; in DRI2 gibt es beispielsweise eine DRI2Authenticate- Anfrage die jeder X-Client an den X-Server senden kann.)
  • Der DRM-Master-Prozess wiederum sendet den Token an das DRM-Gerät zurück, indem er das AUTH_MAGIC ioctl aufruft.
  • Das Gerät vergibt Sonderrechte an den Prozessdatei-Handle, dessen Auth-Token mit dem vom DRM-Master empfangenen Token übereinstimmt.

Grafikausführungs-Manager

Aufgrund der zunehmenden Größe des Videospeichers und der wachsenden Komplexität von Grafik-APIs wie OpenGL war die Strategie, den Grafikkartenstatus bei jedem Kontextwechsel neu zu initialisieren, leistungsmäßig zu teuer. Außerdem brauchten moderne Linux-Desktops eine optimale Möglichkeit, Off-Screen-Puffer mit dem Compositing-Manager zu teilen . Diese Anforderungen führten zur Entwicklung neuer Methoden zur Verwaltung von Grafikpuffern innerhalb des Kernels. Als eine dieser Methoden hat sich der Graphics Execution Manager (GEM) herauskristallisiert.

GEM bietet eine API mit expliziten Speicherverwaltungsprimitiven . Durch GEM kann ein User-Space-Programm im GPU-Videospeicher lebende Speicherobjekte erstellen, verarbeiten und zerstören. Diese als "GEM-Objekte" bezeichneten Objekte sind aus der Sicht des User-Space-Programms persistent und müssen nicht jedes Mal neu geladen werden, wenn das Programm die Kontrolle über die GPU wiedererlangt. Wenn ein User-Space-Programm einen Teil des Videospeichers benötigt (um einen Framebuffer , eine Textur oder andere von der GPU benötigte Daten zu speichern ), fordert es die Zuweisung an den DRM-Treiber mithilfe der GEM-API an. Der DRM-Treiber verfolgt den verwendeten Videospeicher und ist in der Lage, der Anforderung nachzukommen, wenn freier Speicher verfügbar ist, und gibt einen "Handle" an den Benutzerraum zurück, um den zugewiesenen Speicher bei kommenden Operationen weiter zu beziehen. Die GEM-API bietet auch Operationen zum Auffüllen des Puffers und zum Freigeben, wenn er nicht mehr benötigt wird. Speicher von nicht freigegebenen Handles GEM gestellt werden , wenn der Anwender-Space - Prozess des DRM - Gerät schließt Deskriptordatei -intentionally oder weil es endet.

GEM ermöglicht auch zwei oder mehr Userspace- Prozessen , die dasselbe DRM-Gerät (daher denselben DRM-Treiber) verwenden, ein GEM-Objekt gemeinsam zu nutzen. GEM-Handles sind lokale 32-Bit-Ganzzahlen, die für einen Prozess eindeutig sind, aber in anderen Prozessen wiederholbar sind und daher nicht für die gemeinsame Nutzung geeignet sind. Was benötigt wird, ist ein globaler Namespace, und GEM stellt einen durch die Verwendung von globalen Handles namens GEM-Namen bereit . Ein GEM-Name bezieht sich auf ein und nur ein GEM-Objekt, das innerhalb desselben DRM-Geräts von demselben DRM-Treiber unter Verwendung einer eindeutigen 32-Bit- Ganzzahl erstellt wurde . GEM bietet eine Operation flink , um einen GEM-Namen von einem GEM-Handle abzurufen . Der Prozess kann diesen GEM-Namen (32-Bit-Ganzzahl) dann unter Verwendung eines beliebigen verfügbaren IPC- Mechanismus an einen anderen Prozess weitergeben . Der GEM-Name kann vom Empfängerprozess verwendet werden, um ein lokales GEM-Handle zu erhalten, das auf das ursprüngliche GEM-Objekt zeigt.

Leider ist die Verwendung von GEM-Namen zur gemeinsamen Nutzung von Puffern nicht sicher. Ein bösartiger Drittanbieterprozess, der auf dasselbe DRM-Gerät zugreift, könnte versuchen, den GEM-Namen eines Puffers zu erraten, der von anderen beiden Prozessen gemeinsam genutzt wird, indem er einfach 32-Bit-Ganzzahlen untersucht. Sobald ein GEM-Name gefunden wurde, kann auf seinen Inhalt zugegriffen und dieser geändert werden, wodurch die Vertraulichkeit und Integrität der Informationen des Puffers verletzt wird . Dieser Nachteil wurde später durch die Einführung der DMA-BUF- Unterstützung in DRM überwunden , da DMA-BUF Puffer im Benutzerraum als Dateideskriptoren darstellt, die sicher gemeinsam genutzt werden können .

Eine weitere wichtige Aufgabe für jedes Videospeicherverwaltungssystem neben der Verwaltung des Videospeicherplatzes ist die Verwaltung der Speichersynchronisation zwischen der GPU und der CPU. Aktuelle Speicherarchitekturen sind sehr komplex und beinhalten normalerweise verschiedene Cache- Ebenen für den Systemspeicher und manchmal auch für den Videospeicher. Daher sollten Videospeichermanager auch die Cache-Kohärenz handhaben, um sicherzustellen, dass die zwischen CPU und GPU geteilten Daten konsistent sind. Dies bedeutet, dass die Interna der Videospeicherverwaltung häufig stark von den Hardwaredetails der GPU und der Speicherarchitektur abhängen und somit treiberspezifisch sind.

GEM wurde ursprünglich von Intel- Ingenieuren entwickelt, um einen Videospeicher-Manager für seinen i915-Treiber bereitzustellen. Die Intel GMA 9xx- Familie sind integrierte GPUs mit einer Uniform Memory Architecture (UMA), bei der sich GPU und CPU den physischen Speicher teilen und es keinen dedizierten VRAM gibt. GEM definiert "Speicherdomänen" für die Speichersynchronisation, und obwohl diese Speicherdomänen GPU-unabhängig sind, wurden sie speziell für eine UMA-Speicherarchitektur entwickelt, was sie für andere Speicherarchitekturen wie solche mit separatem VRAM weniger geeignet macht. Aus diesem Grund haben andere DRM-Treiber beschlossen, die GEM-API für User-Space-Programme bereitzustellen, aber intern haben sie einen anderen Speichermanager implementiert, der besser für ihre spezielle Hardware und Speicherarchitektur geeignet ist.

Die GEM-API bietet auch ioctls zur Steuerung des Ausführungsflusses (Befehlspuffer), aber sie sind Intel-spezifisch und können mit Intel i915 und späteren GPUs verwendet werden. Kein anderer DRM-Treiber hat versucht, einen Teil der GEM-API über die speicherverwaltungsspezifischen ioctls hinaus zu implementieren.

Übersetzungstabellen-Maps

Translation Table Maps (TTM) ist der Name des generischen Speichermanagers für GPUs, der vor GEM entwickelt wurde. Es wurde speziell für die Verwaltung der verschiedenen Speichertypen entwickelt, auf die eine GPU zugreifen kann, einschließlich dedizierter Video-RAM (normalerweise in der Grafikkarte installiert) und Systemspeicher, auf den über eine E/A-Speicherverwaltungseinheit namens Graphics Address Remapping Table (GART) zugegriffen werden kann. . TTM sollte auch die Teile des Video-RAM verarbeiten, die nicht direkt von der CPU adressiert werden können, und dies mit der bestmöglichen Leistung tun, wenn man bedenkt, dass Grafikanwendungen im Benutzerbereich normalerweise mit großen Videodatenmengen arbeiten. Ein weiterer wichtiger Punkt war, die Konsistenz zwischen den verschiedenen beteiligten Speichern und Caches aufrechtzuerhalten.

Das Hauptkonzept von TTM sind die "Pufferobjekte", Bereiche des Videospeichers, die irgendwann von der GPU adressierbar sein müssen. Wenn eine Grafikanwendung im Benutzerbereich Zugriff auf ein bestimmtes Pufferobjekt wünscht (normalerweise um es mit Inhalt zu füllen), kann es sein, dass TTM eine Verlagerung in einen von der CPU adressierbaren Speichertyp erfordert. Weitere Verlagerungen – oder GART-Mapping-Operationen – können passieren, wenn die GPU Zugriff auf ein Pufferobjekt benötigt, es sich aber noch nicht im Adressraum der GPU befindet. Jeder dieser Verlagerungsvorgänge muss alle damit verbundenen Daten- und Cache-Kohärenzprobleme behandeln.

Ein weiteres wichtiges TTM-Konzept sind Zäune . Zäune sind im Wesentlichen ein Mechanismus, um die Parallelität zwischen der CPU und der GPU zu verwalten. Ein Zaun verfolgt, wenn ein Pufferobjekt nicht mehr von der GPU verwendet wird, im Allgemeinen, um jeden User-Space-Prozess mit Zugriff darauf zu benachrichtigen.

Die Tatsache, dass TTM versucht hat, alle Arten von Speicherarchitekturen, auch solche mit und ohne dedizierten VRAM, in geeigneter Weise zu verwalten und alle erdenklichen Funktionen in einem Speichermanager für den Einsatz mit jeder Art von Hardware bereitzustellen, führte zu einer übermäßig komplexen Lösung mit einer API, die weit größer ist als benötigt. Einige DRM-Entwickler dachten, dass es nicht gut zu einem bestimmten Treiber passen würde, insbesondere nicht zur API. Als GEM als einfacherer Speichermanager auftauchte, wurde seine API der von TTM vorgezogen. Einige Treiberentwickler waren jedoch der Meinung, dass der von TTM gewählte Ansatz besser für diskrete Grafikkarten mit dediziertem Videospeicher und IOMMUs geeignet ist, und beschlossen daher, TTM intern zu verwenden, während sie ihre Pufferobjekte als GEM-Objekte bereitstellen und somit die GEM-API unterstützen. Beispiele für aktuelle Treiber, die TTM als internen Speichermanager verwenden, aber eine GEM-API bereitstellen, sind der Radeon-Treiber für AMD-Grafikkarten und der Nouveau- Treiber für NVIDIA-Grafikkarten.

DMA-Puffer-Sharing und PRIME

Die DMA Buffer Sharing API (oft als DMA-BUF abgekürzt) ist eine interne Linux-Kernel- API, die entwickelt wurde, um einen generischen Mechanismus zur gemeinsamen Nutzung von DMA- Puffer für mehrere Geräte bereitzustellen, die möglicherweise von verschiedenen Typen von Gerätetreibern verwaltet werden. Beispielsweise könnten ein Video4Linux- Gerät und ein Grafikadaptergerät Puffer über DMA-BUF gemeinsam nutzen, um eine Nullkopie der Daten eines Videostreams zu erreichen, der von dem ersten erzeugt und von diesem verbraucht wird. Jeder Linux- Gerätetreiber kann diese API als Exporter, als Benutzer (Verbraucher) oder beides implementieren.

Diese Funktion wurde zum ersten Mal in DRM genutzt, um PRIME zu implementieren, eine Lösung für das GPU-Offloading , die DMA-BUF verwendet, um die resultierenden Framebuffer zwischen den DRM-Treibern der diskreten und der integrierten GPU zu teilen. Ein wichtiges Merkmal von DMA-BUF besteht darin, dass ein gemeinsam genutzter Puffer dem Benutzerbereich als Dateideskriptor präsentiert wird . Für die Entwicklung von PRIME wurden der DRM-API zwei neue ioctls hinzugefügt, eine zur Konvertierung eines lokalen GEM-Handles in einen DMA-BUF-Dateideskriptor und eine andere für den genau entgegengesetzten Vorgang.

Diese beiden neuen ioctls wurden später wiederverwendet, um die inhärente Unsicherheit des GEM-Puffersharings zu beheben. Im Gegensatz zu GEM-Namen können Dateideskriptoren nicht erraten werden (sie sind kein globaler Namespace), und Unix-Betriebssysteme bieten eine sichere Möglichkeit, sie mithilfe der SCM_RIGHTS-Semantik durch einen Unix-Domain-Socket zu übergeben. Ein Prozess, der ein GEM-Objekt mit einem anderen Prozess teilen möchte, kann sein lokales GEM-Handle in einen DMA-BUF-Dateideskriptor konvertieren und an den Empfänger übergeben, der wiederum sein eigenes GEM-Handle vom empfangenen Dateideskriptor erhalten kann. Diese Methode wird von DRI3 verwendet , um Puffer zwischen dem Client und dem X-Server und auch von Wayland gemeinsam zu nutzen .

Kernel-Modus-Einstellung

Es muss ein "DRM-Master" im User-Space vorhanden sein, dieses Programm hat exklusiven Zugriff auf KMS.

Um richtig zu funktionieren, muss eine Grafikkarte oder ein Grafikadapter einen Modus einstellen – eine Kombination aus Bildschirmauflösung , Farbtiefe und Bildwiederholfrequenz –, der innerhalb des Wertebereichs liegt, der von ihr selbst und dem angeschlossenen Bildschirm unterstützt wird . Dieser Vorgang wird als Moduseinstellung bezeichnet und erfordert normalerweise Rohzugriff auf die Grafikhardware – dh die Fähigkeit, in bestimmte Register der Grafikkarte zu schreiben. Eine Moduseinstellungsoperation muss durchgeführt werden, bevor mit der Verwendung des Framebuffers begonnen wird und auch wenn der Modus von einer Anwendung oder dem Benutzer geändert werden muss.

In der Anfangszeit waren die User-Space-Programme, die den grafischen Framebuffer verwenden wollten, auch für die Mode-Setting-Operationen verantwortlich und mussten daher mit privilegiertem Zugriff auf die Videohardware laufen. In Betriebssystemen des Unix-Typs war der X-Server das prominenteste Beispiel, und seine Implementierung der Moduseinstellung lebte im DDX-Treiber für jeden spezifischen Grafikkartentyp. Dieser Ansatz, der später als User Space Mode-Setting oder UMS bezeichnet wird, wirft mehrere Probleme auf. Es durchbricht nicht nur die Isolierung, die Betriebssysteme zwischen Programmen und Hardware bieten sollten, was sowohl Stabilitäts- als auch Sicherheitsbedenken aufwirft, sondern könnte auch die Grafikhardware in einem inkonsistenten Zustand hinterlassen, wenn zwei oder mehr User-Space-Programme versuchen, die Moduseinstellung am gleiche Zeit. Um diese Konflikte zu vermeiden, wurde der X-Server in der Praxis das einzige User-Space-Programm, das Moduseinstellungsoperationen durchführte; die restlichen User-Space-Programme verließen sich auf den X-Server, um den entsprechenden Modus einzustellen und alle anderen Operationen, die das Einstellen des Modus beinhalten, zu handhaben. Anfangs wurde die Moduseinstellung ausschließlich während des Startvorgangs des X-Servers vorgenommen, später erhielt der X-Server jedoch die Möglichkeit, dies während des Betriebs zu tun. Die Erweiterung XFree86-VidModeExtension wurde in XFree86 3.1.2 eingeführt, damit jeder X-Client Modeline- Änderungen (Auflösung) an den X-Server anfordern kann . Die VidMode-Erweiterung wurde später durch die allgemeinere XRandR- Erweiterung ersetzt.

Dies war jedoch nicht der einzige Code, der die Moduseinstellung in einem Linux- System durchführte. Während des Systemstartvorgangs muss der Linux-Kernel einen minimalen Textmodus für die virtuelle Konsole festlegen (basierend auf den Standardmodi, die von VESA-BIOS- Erweiterungen definiert werden ). Auch der Linux-Kernel-Framebuffer-Treiber enthielt Modus-Einstellungscode zum Konfigurieren von Framebuffer-Geräten. Um Konflikte bei der Moduseinstellung zu vermeiden, behandelte der XFree86 Server – und später der X.Org Server – den Fall, dass der Benutzer von der grafischen Umgebung zu einer virtuellen Textkonsole wechselte, indem er seinen Moduseinstellungszustand speicherte und ihn beim Wechsel des Benutzers wieder herstellte zurück zu X. Dieser Vorgang verursachte ein lästiges Flackern beim Übergang und kann auch fehlschlagen, was zu einer beschädigten oder unbrauchbaren Ausgabeanzeige führt.

Der Ansatz zur Einstellung des Benutzerbereichsmodus verursachte auch andere Probleme:

  • Der Suspend/Resume-Prozess muss sich auf User-Space-Tools verlassen, um den vorherigen Modus wiederherzustellen. Ein einzelner Fehler oder Absturz eines dieser Programme könnte das System aufgrund einer Modeset-Fehlkonfiguration ohne funktionierende Anzeige hinterlassen und daher unbrauchbar machen.
  • Es war auch für den Kernel unmöglich, Fehler- oder Debug-Meldungen anzuzeigen, wenn sich der Bildschirm in einem Grafikmodus befand – zum Beispiel wenn X lief –, da der Kernel nur die Modi kannte, die die Standardtextmodi des VESA-BIOS waren.
  • Ein dringenderes Problem war die Verbreitung von grafischen Anwendungen, die den X-Server umgehen, und das Aufkommen anderer Grafik-Stack-Alternativen zu X, wodurch die Duplizierung von Code zur Moduseinstellung im gesamten System noch weiter ausgedehnt wurde.

Um diese Probleme zu beheben, wurde der Code zur Moduseinstellung an eine einzige Stelle im Kernel verschoben, insbesondere in das vorhandene DRM-Modul. Dann sollte jeder Prozess – einschließlich des X-Servers – in der Lage sein, dem Kernel zu befehlen, Operationen zur Einstellung des Modus durchzuführen, und der Kernel würde sicherstellen, dass gleichzeitige Operationen nicht zu einem inkonsistenten Zustand führen. Die neue Kernel-API und der Code, der dem DRM-Modul hinzugefügt wurde, um diese Moduseinstellungsvorgänge durchzuführen, wurde Kernel-Moduseinstellung (KMS) genannt.

Die Kernel-Modus-Einstellung bietet mehrere Vorteile. Am unmittelbarsten ist natürlich die Entfernung von doppeltem Code zur Moduseinstellung, sowohl aus dem Kernel (Linux-Konsole, fbdev) als auch aus dem Benutzerbereich (X Server DDX-Treiber). KMS erleichtert auch das Schreiben alternativer Grafiksysteme, die jetzt keinen eigenen Code zur Moduseinstellung implementieren müssen. Durch die Bereitstellung einer zentralisierten Modusverwaltung löst KMS die Flackerprobleme beim Wechsel zwischen Konsole und X sowie zwischen verschiedenen Instanzen von X (schneller Benutzerwechsel). Da es im Kernel verfügbar ist, kann es auch zu Beginn des Bootvorgangs verwendet werden, wodurch ein Flackern durch Moduswechsel in diesen frühen Stadien vermieden wird.

Die Tatsache , dass KMS Teil des Kernels ist , ermöglicht es ihm , Ressourcen zu verwenden , die nur im Kernelbereich verfügbar sind , wie zB Interrupts . Zum Beispiel vereinfacht die Moduswiederherstellung nach einem Suspend/Resume-Prozess viel, indem sie vom Kernel selbst verwaltet wird, und verbessert nebenbei die Sicherheit (keine User-Space-Tools mehr, die Root-Berechtigungen benötigen). Der Kernel ermöglicht auch das Hotplug neuer Anzeigegeräte problemlos und löst damit ein seit langem bestehendes Problem. Die Moduseinstellung hängt auch eng mit der Speicherverwaltung zusammen – da Framebuffer im Grunde Speicherpuffer sind – wird eine enge Integration mit dem Grafikspeichermanager dringend empfohlen. Das ist der Hauptgrund, warum der Code zur Einstellung des Kernelmodus in DRM integriert wurde und nicht als separates Subsystem.

Um die Abwärtskompatibilität der DRM-API nicht zu beeinträchtigen, wird die Kernel-Modus-Einstellung als zusätzliche Treiberfunktion bestimmter DRM-Treiber bereitgestellt . Jeder DRM-Treiber kann das Flag DRIVER_MODESET bereitstellen, wenn er sich beim DRM-Kern registriert, um anzugeben, dass er die KMS-API unterstützt. Diese Treiber, die Kernel Mode-Setting implementieren, werden oft als KMS-Treiber bezeichnet , um sie von den Legacy-DRM-Treibern ohne KMS zu unterscheiden.

KMS wurde in einem solchen Ausmaß übernommen, dass bestimmte Treiber, denen die 3D-Beschleunigung fehlt (oder für die der Hardwarehersteller diese nicht bereitstellen oder implementieren möchte), dennoch die KMS-API ohne den Rest der DRM-API implementieren.

KMS-Gerätemodell

KMS modelliert und verwaltet die Ausgabegeräte als eine Reihe abstrakter Hardwareblöcke, die üblicherweise in der Anzeigeausgabepipeline eines Anzeigecontrollers zu finden sind . Diese Blöcke sind:

  • CRTCs : Jeder CRTC (vom CRT- Controller) repräsentiert eine Scanout-Engine des Display-Controllers, die auf einen Scanout-Puffer ( Framebuffer ) zeigt. Der Zweck einer CRTC besteht darin, die aktuell im Scanout-Puffer befindlichen Pixeldaten zu lesen und daraus mit Hilfe einer PLL-Schaltung das Videomodus-Timing-Signal zu erzeugen . Die Anzahl der verfügbaren CRTCs bestimmt, wie viele unabhängige Ausgabegeräte die Hardware gleichzeitig verarbeiten kann, sodass zur Verwendung von Mehrkopfkonfigurationen mindestens ein CRTC pro Anzeigegerät erforderlich ist. Zwei oder mehr-CRTCs kann auch Arbeiten im Clone - Modus , wenn sie scannen aus dem gleichen Framebuffer das gleiche Bild auf mehrere Ausgabegeräte zu senden.
  • Anschlüsse : ein Verbinder darstellt , in dem die Anzeigesteuereinheit das Videosignal von einem scanout Betrieb sendet angezeigt werden. Normalerweise entspricht das KMS-Konzept eines Anschlusses einem physischen Anschluss ( VGA , DVI , FPD-Link , HDMI , DisplayPort , S-Video , ...) in der Hardware, an dem ein Ausgabegerät ( Monitor , Laptop- Panel, ...) ) ist dauerhaft oder kann temporär angebracht werden. Informationen zum aktuellen physisch angeschlossenen Ausgabegerät – wie Verbindungsstatus, EDID- Daten, DPMS- Status oder unterstützte Videomodi – werden ebenfalls im Anschluss gespeichert.
  • Codierer : Der Display-Controller muss das Videomodus-Timing-Signal von der CRTC in einem für den vorgesehenen Anschluss geeigneten Format codieren. Ein Codierer stellt den Hardwareblock dar, der eine dieser Codierungen durchführen kann. Beispiele für Kodierungen – für digitale Ausgaben – sind TMDS und LVDS ; für analoge Ausgänge wie VGA und TV- Ausgang werden im Allgemeinen spezielle DAC- Blöcke verwendet. Ein Anschluss kann jeweils nur das Signal von einem Encoder empfangen, und jeder Anschlusstyp unterstützt nur einige Codierungen. Es kann auch zusätzliche physikalische Einschränkungen geben, durch die nicht jeder CRTC mit jedem verfügbaren Encoder verbunden ist, was die möglichen Kombinationen von CRTC-Encoder-Connector einschränkt.
  • Ebenen : Eine Ebene ist kein Hardwareblock, sondern ein Speicherobjekt, das einen Puffer enthält, aus dem eine Scanout-Engine (ein CRTC) gespeist wird. Die Ebene, die den Framebuffer enthält, wird als primäre Ebene bezeichnet , und jeder CRTC muss eine zugeordnet sein, da sie die Quelle für die CRTC ist, um den Videomodus zu bestimmen – Anzeigeauflösung (Breite und Höhe), Pixelgröße, Pixelformat, Bildwiederholfrequenz, usw. Einem CRTC können auch Cursor-Ebenen zugeordnet sein, wenn der Display-Controller Hardware-Cursor-Overlays unterstützt, oder sekundäre Ebenen, wenn er in der Lage ist, aus zusätzlichen Hardware-Overlays zu scannen und das endgültige Bild, das an die Ausgabe gesendet wird, "on the fly" zu komponieren oder zu mischen Gerät.

Atomare Anzeige

In den letzten Jahren gab es fortlaufende Bemühungen, bei einigen regulären Vorgängen im Zusammenhang mit der KMS-API Atomizität zu erzielen, insbesondere bei der Moduseinstellung und den Seitenumkehrvorgängen . Diese erweiterte KMS-API wird als Atomic Display bezeichnet (früher bekannt als Atomic Mode-Setting und Atomic oder Nuclear Pageflip ).

Der Zweck der atomaren Moduseinstellung besteht darin, einen korrekten Moduswechsel in komplexen Konfigurationen mit mehreren Einschränkungen zu gewährleisten, indem Zwischenschritte vermieden werden, die zu einem inkonsistenten oder ungültigen Videozustand führen könnten; es vermeidet auch riskante Videozustände, wenn ein fehlgeschlagener Moduseinstellungsprozess rückgängig gemacht werden muss ("Rollback"). Die atomare Moduseinstellung ermöglicht es, im Voraus zu wissen, ob eine bestimmte spezifische Moduskonfiguration geeignet ist, indem Modustestfunktionen bereitgestellt werden. Wenn ein atomarer Modus getestet und seine Gültigkeit bestätigt wird, kann er mit einer einzigen unteilbaren (atomaren) Commit- Operation angewendet werden. Sowohl Test- als auch Commit-Operationen werden von demselben neuen ioctl mit unterschiedlichen Flags bereitgestellt .

Atomic Umblättern auf der anderen Seite ermöglicht es mehreren Ebenen auf dem gleichen Ausgang (beispielsweise der Hauptebene, die Cursor - Ebene und möglicherweise einige Overlays oder sekundären Ebenen) synchronisiert alle innerhalb derselben zu aktualisieren VBLANK Intervall, eine richtige Anzeige ohne Einreißen gewährleistet wird . Diese Anforderung ist besonders relevant für mobile und eingebettete Display-Controller, die dazu neigen, mehrere Ebenen/Overlays zu verwenden, um Strom zu sparen.

Die neue atomare API baut auf der alten KMS-API auf. Es verwendet das gleiche Modell und die gleichen Objekte (CRTCs, Encoder, Konnektoren, Ebenen, ...), jedoch mit einer zunehmenden Anzahl von Objekteigenschaften, die geändert werden können. Die atomare Prozedur basiert auf der Änderung der relevanten Eigenschaften, um den Zustand zu erstellen, den wir testen oder festschreiben möchten. Die Eigenschaften, die wir ändern möchten, hängen davon ab, ob wir eine Moduseinstellung (meist CRTCs, Encoder- und Konnektoreigenschaften) oder Seitenumblättern (normalerweise Ebeneneigenschaften) vornehmen möchten. Das ioctl ist in beiden Fällen gleich, der Unterschied besteht in der Liste der Eigenschaften, die mit jedem übergeben werden.

Knoten rendern

In der ursprünglichen DRM-API wird das DRM-Gerät sowohl für privilegierte (Moduseinstellung, andere Anzeigesteuerung) als auch für nicht-privilegierte (Rendering, GPGPU- Berechnung) Operationen verwendet. Aus Sicherheitsgründen erfordert das Öffnen der zugehörigen DRM-Gerätedatei spezielle Privilegien, die "entspricht Root-Privilegien" sind. Dies führt zu einer Architektur, in der nur einige zuverlässige User-Space-Programme (der X-Server, ein grafischer Compositor, ...) vollen Zugriff auf die DRM-API haben, einschließlich der privilegierten Teile wie der Modeset-API. Die restlichen Benutzerraumanwendungen, die GPGPU-Berechnungen rendern oder durchführen möchten, sollten vom Eigentümer des DRM-Geräts ("DRM-Master") durch die Verwendung einer speziellen Authentifizierungsschnittstelle gewährt werden. Dann können die authentifizierten Anwendungen mit einer eingeschränkten Version der DRM-API ohne privilegierte Operationen rendern oder Berechnungen durchführen. Dieses Design stellt eine strenge Einschränkung: Es muss immer ein laufender Grafikserver (der X-Server, ein Wayland-Kompositor, ...) als DRM-Master eines DRM-Geräts fungieren, damit anderen User-Space-Programmen die Nutzung der Gerät, auch in Fällen, in denen keine Grafikanzeige wie GPGPU-Berechnungen verwendet wird. /dev/dri/cardX

Das Konzept der „Render-Nodes“ versucht, diese Szenarien zu lösen, indem die DRM-User-Space-API in zwei Schnittstellen – eine privilegierte und eine nicht-privilegierte – aufgeteilt wird und für jede einzelne Gerätedateien (oder „Nodes“) verwendet werden. Für jede gefundene GPU erstellt der entsprechende DRM-Treiber – sofern er die Render-Knoten-Funktion unterstützt – zusätzlich zum primären Knoten eine Gerätedatei , die als Render-Knoten bezeichnet wird . Clients, die ein direktes Rendering-Modell verwenden, und Anwendungen, die die Rechenfunktionen einer GPU nutzen möchten, können dies ohne zusätzliche Berechtigungen tun, indem sie einfach einen vorhandenen Rendering-Knoten öffnen und GPU-Operationen unter Verwendung der begrenzten Untermenge der DRM-API, die von unterstützt wird, verteilen diese Knoten – vorausgesetzt, sie verfügen über Dateisystemberechtigungen zum Öffnen der Gerätedatei. Anzeigeserver, Compositors und jedes andere Programm, das die Modeset-API oder eine andere privilegierte Operation erfordert, müssen den standardmäßigen primären Knoten öffnen, der Zugriff auf die vollständige DRM-API gewährt, und ihn wie gewohnt verwenden. Renderknoten verbieten ausdrücklich den GEM- Flink- Vorgang, um die Pufferfreigabe mit unsicheren globalen GEM-Namen zu verhindern. nur PRIME- Dateideskriptoren (DMA-BUF) können verwendet werden, um Puffer mit einem anderen Client, einschließlich des Grafikservers, gemeinsam zu nutzen. /dev/dri/renderDX/dev/dri/cardX

Hardware-Unterstützung

DRM wird von Grafiktreibern im Benutzermodus verwendet, wie zB AMD Catalyst oder Mesa 3D . User-Space-Programme verwenden die Linux-Systemaufrufschnittstelle, um auf DRM zuzugreifen. DRM erweitert das Linux System Call Interface um eigene Systemaufrufe.

Das Linux-DRM-Subsystem enthält kostenlose und Open-Source- Treiber zur Unterstützung von Hardware der 3 wichtigsten Hersteller von GPUs für Desktop-Computer (AMD, NVIDIA und Intel) sowie von einer wachsenden Zahl mobiler GPUs und System-on-a-Chip (SoC) Integratoren. Die Qualität jedes Treibers variiert stark, abhängig vom Grad der Zusammenarbeit des Herstellers und anderen Faktoren.

DRM-Treiber
Treiber Da Kernel Unterstützte Hardware Anbieterunterstützung Status/Hinweise
radeon 2.4.1 AMD (ehemals ATi) Radeon GPU-Serie mit den Architekturen TeraScale und GCN 1st & 2nd Gen . Einschließlich Modelle der R100 / 200 / 300 / 400 , Radeon X1000 , HD 2000 / 4000 / 5000 / 6000 / 7000 / 8000 , R5/R7/R9 200 / 300 Serie und Kaveri APUs. Jawohl Aktiv
i915 2.6.9 Intel GMA 830M, 845G, 852GM, 855GM, 865G, 915G, 945G, 965G, G35, G41, G43, G45 Chipsätze. Intel HD und Iris Graphics HD Graphics 2000/3000/2500/4000/4200/4400/4600/P4600/P4700/5000, Iris Graphics 5100, Iris Pro Graphics 5200 integrierte GPUs. Jawohl Aktiv
neu 2.6.33 NVIDIA Tesla , Fermi , Kepler , Maxwell basierte GeForce GPUs, Tegra K1 , X1 SoC Teilweise Aktiv
exynos 3.2 Samsung ARM-basierte Exynos-SoCs
vmwgfx 3.2 (aus Inszenierung) Virtuelle GPU für den VMware SVGA2 virtueller Fahrer
gma500 3.3 (aus Inszenierung) Intel GMA 500 und andere auf Imagination Technologies ( PowerVR ) basierende Grafik-GPUs experimenteller 2D-Nur-KMS-Treiber
ast 3.5 ASpeed ​​Technologies 2000-Serie Experimental-
mgag200 3.5 Matrox MGA-G200 Server-Display-Engines Nur KMS
schmobil 3.7 Renesas SH Mobile
tegra 3.8 Nvidia Tegra 20, Tegra30 SoCs Jawohl Aktiv
omadrm 3.9 Texas Instruments OMAP 5-SoCs
rcar-du 3.11 Renesas R-Car SoC-Anzeigeeinheiten
msm 3.12 Qualcomm ‚s Adreno A2xx / A3xx / A4xx GPU Familien ( Snapdragon SOCs)
Armada 3.13 Marvell Armada 510-SoCs
bochs 3.14 Virtuelle VGA- Karten mit Bochs dispi-vga-Schnittstelle (z. B. QEMU stdvga) virtueller Fahrer
halt 3.17 STMicroelectronics SoC stiH41x-Serie
imx 3.19 (aus Inszenierung) Freescale i.MX- SoCs
Steinschlag 3.19 Rockchip SoC-basierte GPUs Nur KMS
amdgpu 4.2 AMD Radeon GPU-Serie mit den Architekturen GCN 3. & 4. Generation . Darunter Modelle der Radeon Rx 200 / 300 / 400 / 500 Serie sowie Carrizo und Bristol & Stoney Ridge APUs. Jawohl Aktiv
virtio 4.2 virtueller GPU-Treiber für QEMU- basierte Virtual Machine Manager (wie KVM oder Xen ) virtueller Fahrer
vc4 4.4 Himbeer Pi ‚s Broadcom BCM2835 und BCM2836 SoCs ( VideoCore IV GPU)
Ätnaviv 4.5 Vivante GPU-Kerne finden sich in mehreren SoCs wie Marvell ARMADA und Freescale i.MX6 Series
sun4i 4.7 Allwinner- SoCs (ARM Mali-400- GPU)
Kirin 4.7 HiSilicon Kirin hi6220 SoC (ARM Mali 450-MP4- GPU)
mediatek 4.7 MediaTek MT8173 SoC (Imagination PowerVR GX6250 GPU)
Hibmc 4.10 HiSilicon hi1710 Huawei iBMC SoC ( Silicon Image SM750 GPU-Kern) Nur KMS
vboxvideo 4.13 (aus Inszenierung) Virtueller GPU-Treiber für VirtualBox (VBoxVGA-GPU) virtueller Fahrer
Lima 5.2 ARM Mali 4xx-GPUs
panfrost 5.2 ARM Mali Txxx (Midgard) und Gxx (Bifrost) GPUs
hyperv_drm 5.14 Virtueller GPU-Treiber für synthetisches Hyper-V- Videogerät virtueller Fahrer
simpledrm 5.14 GPU-Treiber für von der Firmware bereitgestellte Framebuffer ( UEFI GOP , VESA BIOS Extensions , Embedded Systems )

Es gibt auch eine Reihe von Treibern für alte, veraltete Hardware, die in der nächsten Tabelle zu historischen Zwecken aufgeführt sind. Einige davon bleiben noch im Kernel-Code, andere wurden bereits entfernt.

Historische DRM-Treiber
Treiber Da Kernel Unterstützte Hardware Status/Hinweise
Gamma 2.3.18 3Dlabs GLINT GMX 2000 Entfernt seit 2.6.14
ffb 2.4 Creator/Creator3D (von Sun Microsystems Ultra- Workstations verwendet) Entfernt seit 2.6.21
tdfx 2.4 3dfx Todesfee / Voodoo3 +
mga 2.4 Matrox G200 / G400 /G450
r128 2.4 ATI Wut 128
i810 2.4 Intel i810
Schwester 2.4.17 SiS 300 /630/540
i830 2.4.20 Intel 830M/845G/852GM/855GM/865G Entfernt seit 2.6.39 (ersetzt durch i915-Treiber)
über 2.6.13 VIA Unichrome / Unichrome Pro
wild 2.6.14 S3-Grafik Savage 3D/MX/IX/4/SuperSavage/Pro/Twister

Entwicklung

Der Direct Rendering Manager wird innerhalb des Linux-Kernels entwickelt und sein Quellcode befindet sich im /drivers/gpu/drmVerzeichnis des Linux-Quellcodes. Der Betreuer des Subsystems ist Dave Airlie, andere Betreuer kümmern sich um bestimmte Fahrer. Wie üblich in der Linux - Kernel - Entwicklung, DRM submaintainers und Mitwirkenden schicken ihren Patches mit neuen Features und Bug - Fixes mit dem Haupt DRM Maintainer , die sie in ihren eigenen Linux integriert Repository . Der DRM-Maintainer schickt seinerseits alle diese Patches, die bereit sind, auf Linus Torvalds gemainlinet zu werden, wenn eine neue Linux-Version veröffentlicht wird. Torvalds hat als Top-Maintainer des gesamten Kernels das letzte Wort darüber, ob ein Patch für die Aufnahme in den Kernel geeignet ist oder nicht.

Aus historischen Gründen wird der Quellcode der Bibliothek libdrm unter dem Dach des Mesa- Projekts gepflegt .

Geschichte

1999, während der Entwicklung von DRI für XFree86 , erstellte Precision Insight die erste Version von DRM für die 3dfx -Grafikkarten als Linux-Kernel- Patch, der im Mesa- Quellcode enthalten war. Später in diesem Jahr wurde der DRM-Code im Linux-Kernel 2.3.18 unter dem /drivers/char/drm/Verzeichnis für Zeichengeräte verankert . In den folgenden Jahren wuchs die Zahl der unterstützten Grafikkarten. Als Linux 2.4.0 im Januar 2001 veröffentlicht wurde, gab es neben 3dfx Voodoo3-Karten bereits Unterstützung für Creative Labs GMX 2000, Intel i810, Matrox G200/G400 und ATI Rage 128, und diese Liste wurde während der 2.4.x-Serie erweitert. mit Treibern für ATI Radeon- Karten, einige SiS-Grafikkarten und Intel 830M und nachfolgende integrierte GPUs.

Die Aufteilung von DRM in zwei Komponenten, DRM-Kern und DRM-Treiber, genannt DRM-Kern/Persönlichkeits-Split, erfolgte in der zweiten Jahreshälfte 2004 und wurde in die Kernel-Version 2.6.11 zusammengeführt. Diese Aufteilung ermöglichte es mehreren DRM-Treibern für mehrere Geräte, gleichzeitig zu arbeiten, was den Weg zur Multi-GPU-Unterstützung ebnete.

Die Idee, den gesamten Einstellungscode für den Videomodus an einer Stelle im Kernel abzulegen, war seit Jahren bekannt, aber die Grafikkartenhersteller hatten argumentiert, dass die einzige Möglichkeit zur Einstellung des Modus darin bestand, die von ihnen bereitgestellten und enthaltenen Routinen zu verwenden das Video-BIOS jeder Grafikkarte. Dieser Code musste im x86- Realmodus ausgeführt werden , was verhinderte, dass er von einem im geschützten Modus laufenden Kernel aufgerufen wurde . Die Situation änderte sich, als Luc Verhaegen und anderen Entwicklern einen Weg gefunden , um den Modus-Einstellung nativ statt BIOS-basierten zu tun, die zeigen , dass es möglich war , es sich mit den normalen Kernel - Code zu tun und den Grundstein legen für das, was werden würde Kernel Mode Setting . Im Mai 2007 veröffentlichte Jesse Barnes ( Intel ) den ersten Vorschlag für eine DRM-Moduseinstellungs- API und eine funktionierende native Implementierung der Moduseinstellung für Intel-GPUs innerhalb des i915 DRM-Treibers. Im Dezember 2007 begann Jerome Glisse, dem radeon DRM-Treiber den nativen Moduseinstellungscode für ATI-Karten hinzuzufügen. Die Arbeit sowohl an der API als auch an den Treibern wurde 2008 fortgesetzt, wurde jedoch durch die Notwendigkeit eines Speichermanagers auch im Kernelbereich verzögert, um die Framebuffer zu verarbeiten.

Im Oktober 2008 brachte der Linux-Kernel 2.6.27 eine umfassende Reorganisation des Quellcodes , bevor einige bedeutende Änderungen anstehen. Der DRM-Quellcodebaum wurde in ein eigenes Quellverzeichnis verschoben /drivers/gpu/drm/und die verschiedenen Treiber wurden in eigene Unterverzeichnisse verschoben. Auch Header wurden in ein neues /include/drmVerzeichnis verschoben .

Die zunehmende Komplexität der Videospeicherverwaltung führte zu mehreren Lösungsansätzen für dieses Problem. Der erste Versuch war der Speichermanager Translation Table Maps (TTM), der von Thomas Hellstrom ( Tungsten Graphics ) in Zusammenarbeit mit Emma Anholt (Intel) und Dave Airlie ( Red Hat ) entwickelt wurde. TTM wurde für die Aufnahme in den Mainline-Kernel 2.6.25 im November 2007 und erneut im Mai 2008 vorgeschlagen, wurde jedoch zugunsten eines neuen Ansatzes namens Graphics Execution Manager (GEM) aufgegeben. GEM wurde zuerst von Keith Packard und Emma Anholt von Intel als einfachere Lösung zur Speicherverwaltung für ihren i915-Treiber entwickelt. GEM wurde gut angenommen und in die im Dezember 2008 veröffentlichte Linux-Kernel-Version 2.6.28 eingearbeitet. Währenddessen musste TTM bis September 2009 warten, um schließlich als Voraussetzung für den neuen Radeon KMS DRM-Treiber in Linux 2.6.31 eingebunden zu werden.

Mit der Speicherverwaltung zur Handhabung von Pufferobjekten konnten DRM-Entwickler dem Kernel endlich die bereits fertige API und die Code-to-do- Moduseinstellung hinzufügen . Diese erweiterte API wird als Kernel Mode-Setting (KMS) bezeichnet und die Treiber, die sie implementieren, werden oft als KMS-Treiber bezeichnet . Im März 2009 wurde KMS zusammen mit der KMS-Unterstützung für den i915-Treiber in die Linux-Kernel-Version 2.6.29 integriert. Die KMS-API ist seit libdrm 2.4.3 für User-Space-Programme verfügbar. Der Userspace X.Org DDX- Treiber für Intel-Grafikkarten war auch der erste, der die neuen GEM- und KMS-APIs verwendet. KMS-Unterstützung für den radeon DRM-Treiber wurde der Linux-Version 2.6.31 vom September 2009 hinzugefügt. Der neue radeon-KMS-Treiber verwendete den TTM-Speichermanager, stellte jedoch GEM-kompatible Schnittstellen und ioctls anstelle von TTM-Schnittstellen bereit.

Seit 2006 entwickelte das Nouveau-Projekt einen freien Software- DRM-Treiber für NVIDIA- GPUs außerhalb des offiziellen Linux-Kernels. 2010 wurde der Nouveau-Quellcode als experimenteller Treiber in Linux 2.6.33 eingebunden. Zum Zeitpunkt der Zusammenführung war der Treiber bereits in KMS konvertiert und nutzte hinter der GEM-API TTM als Speichermanager.

Die neue KMS-API – einschließlich der GEM-API – war ein großer Meilenstein in der Entwicklung von DRM, aber sie stoppte nicht die Erweiterung der API in den folgenden Jahren. KMS erhielt in Linux 2.6.33 Unterstützung für Seitenumblätter in Verbindung mit asynchronen VBLANK- Benachrichtigungen – nur für den i915-Treiber, radeon und nouveau fügten es später während der Veröffentlichung von Linux 2.6.38 hinzu. Die neue Page-Flip-Schnittstelle wurde zu libdrm 2.4.17 hinzugefügt. Anfang 2011, während des Release-Zyklus von Linux 2.6.39, wurden der KMS-API sogenannte Dumb Buffer hinzugefügt – eine hardwareunabhängige, nicht beschleunigte Möglichkeit, einfache Puffer, die als Framebuffer verwendet werden können, zu handhaben. Das Ziel war es, die Komplexität von Anwendungen wie Plymouth zu reduzieren , die keine speziellen beschleunigten Operationen verwenden müssen, die von treiberspezifischen ioctls bereitgestellt werden. Die Funktion wurde von libdrm ab Version 2.4.25 verfügbar gemacht. Später in diesem Jahr erhielt es auch einen neuen Haupttyp von Objekten, die sogenannten Flugzeuge . Ebenen wurden entwickelt, um Hardware-Overlays darzustellen, die von der Scanout-Engine unterstützt werden. Die Flugzeugunterstützung wurde in Linux 3.3 integriert. und libdrm 2.4.30. Ein weiteres Konzept, das der API hinzugefügt wurde – während der Releases von Linux 3.5 und libdrm 2.4.36 – waren generische Objekteigenschaften , eine Methode zum Hinzufügen von generischen Werten zu jedem KMS-Objekt. Eigenschaften sind besonders nützlich, um Objekten wie CRTCs und Ebenen ein spezielles Verhalten oder besondere Eigenschaften zuzuweisen.

Ein früher Machbarkeitsnachweis zur Bereitstellung von GPU-Offloading zwischen DRM-Treibern wurde 2010 von Dave Airlie entwickelt. Da Airlie versuchte, die NVIDIA Optimus- Technologie nachzuahmen , beschloss er, sie "PRIME" zu nennen. Airlie nahm seine Arbeit an PRIME Ende 2011 wieder auf, jedoch basierend auf dem neuen DMA-BUF-Puffersharing- Mechanismus, der mit dem Linux-Kernel 3.3 eingeführt wurde. Die grundlegende DMA-BUF PRIME-Infrastruktur wurde im März 2012 fertiggestellt und in das Release Linux 3.4 sowie in libdrm 2.4.34 integriert. Später während der Linux 3.5-Version implementierten mehrere DRM-Treiber PRIME-Unterstützung, darunter i915 für Intel-Karten, radeon für AMD-Karten und nouveau für NVIDIA-Karten.

In den letzten Jahren wurde die DRM-API schrittweise um neue und verbesserte Funktionen erweitert. Im Jahr 2013 entwickelte David Herrmann im Rahmen von GSoC das Feature Multiple Render Nodes . Sein Code wurde der Linux-Kernelversion 3.12 als experimentelle Funktion hinzugefügt, die von i915-, Radeon- und Nouveau-Treibern unterstützt wird und seit Linux 3.17 standardmäßig aktiviert ist. Im Jahr 2014 entwickelte Matt Roper (Intel) das Konzept der Universal Planes (oder Unified Planes ), bei dem Framebuffer ( Primary Planes ), Overlays ( Secondary Planes ) und Cursors ( Cursor Planes ) alle als ein einziger Objekttyp mit einer einheitlichen API behandelt werden. Die Unterstützung für universelle Ebenen bietet eine konsistentere DRM-API mit weniger, allgemeineren ioctls . Um die API- Abwärtskompatibilität aufrechtzuerhalten , wird die Funktion vom DRM-Kern als zusätzliche Fähigkeit bereitgestellt, die ein DRM-Treiber bereitstellen kann. Die Unterstützung für universelle Ebenen wurde in Linux 3.15 und libdrm 2.4.55 eingeführt. Mehrere Treiber, wie der Intel i915, haben es bereits implementiert.

Die neueste DRM-API-Erweiterung ist die atomare Moduseinstellungs- API, die Atomizität in die Moduseinstellungs- und Seitenwechselvorgänge auf einem DRM-Gerät bringt . Die Idee einer atomaren API zur Moduseinstellung wurde erstmals Anfang 2012 vorgestellt. Ville Syrjälä (Intel) übernahm die Aufgabe, eine solche atomare API zu entwerfen und zu implementieren. Basierend auf seiner Arbeit verfolgte Rob Clark ( Texas Instruments ) einen ähnlichen Ansatz mit dem Ziel, atomare Seitenumblätter zu implementieren. Später im Jahr 2013 wurden beide vorgeschlagenen Funktionen in einem einzigen vereint, wobei ein einziges ioctl für beide Aufgaben verwendet wurde. Da es eine Anforderung war, musste das Feature warten, bis die Unterstützung von Universalflugzeugen Mitte 2014 zusammengeführt wurde. In der zweiten Jahreshälfte 2014 wurde der Atomic Code von Daniel Vetter (Intel) und anderen DRM-Entwicklern stark verbessert, um den Übergang für die bestehenden KMS-Treiber auf das neue Atomic Framework zu erleichtern. All diese Arbeit wurde schließlich in den Versionen Linux 3.19 und Linux 4.0 zusammengeführt und seit Linux 4.2 standardmäßig aktiviert. libdrm hat die neue atomare API seit Version 2.4.62 veröffentlicht. Mehrere Treiber wurden bereits auf die neue atomare API konvertiert. Bis 2018 wurden dem Linux-Kernel zehn neue DRM-Treiber basierend auf diesem neuen Atommodell hinzugefügt.

Annahme

Das Kernel-Subsystem von Direct Rendering Manager wurde ursprünglich für die Verwendung mit der neuen Direct Rendering Infrastructure des XFree86 4.0-Anzeigeservers entwickelt, der später von seinem Nachfolger, dem X.Org Server, übernommen wurde . Daher waren die Hauptbenutzer von DRM DRI-Clients, die auf die hardwarebeschleunigte OpenGL- Implementierung, die in der Mesa 3D- Bibliothek lebt , sowie auf den X-Server selbst verweisen. Heutzutage wird DRM auch von mehreren Wayland-Kompositoren verwendet , einschließlich des Weston- Referenzkompositors. kmscon ist eine virtuelle Konsolenimplementierung, die im Benutzerbereich unter Verwendung von DRM-KMS-Einrichtungen ausgeführt wird.

Im Jahr 2015 erhielt die Version 358.09 (Beta) des proprietären Nvidia GeForce-Treibers Unterstützung für die DRM-Moduseinstellungsschnittstelle, die als neuer Kernel-Blob namens nvidia-modeset.ko. Diese neue Treiberkomponente arbeitet in Verbindung mit dem nvidia.koKernel-Modul, um die Display-Engine (dh den Display-Controller) der GPU zu programmieren.

Siehe auch

Verweise

Externe Links