DRM 架構介紹
1、 DRM 簡介(Direct Rendering Manager)
傳統 linux 顯示設備驅動開發時,通常使用 FB 驅動架構,隨着顯卡性能升級:顯示覆蓋(菜單層級)、GPU 加速、硬件光標,傳統 FB 架構無法很好支持,此外,對於多應用的訪問衝突也無法很好控制。在這樣的背景下,DRM 應用而生。
DRM 是 linux 內核中負責與顯卡交互的管理架構,用戶空間很方便的利用 DRM 提供的 API,實現 3D 渲染、視頻解碼和 GPU 計算等工作。
1.1 DRM 發展歷史
-
1999 年,Precision Insight 公司首次爲 XFree86 4.0 Server 開發 DRI 顯示框架,用於更好的適配 3DFX 公司顯卡,初版 DRM 代碼產出後,接下來的幾年時間裏,DRM 所支持的顯卡列表不斷被擴充。
-
2008 年 10 月,Linux kernel 2.6.27 進行了一次重大的源碼重組:DRM 的整套源碼被放到了 / drivers/gpu/drm / 目錄下,不同的 GPU 廠商代碼也被放到了各自子目錄下。
-
2014 年 6 月,Atomic API 被添加到 Linux 3.16,許多驅動也都轉而使用這些新的 API。
-
2018 年,又有 10 個基於 atomic 框架的 DRM 新增驅動被添加到 Linux kernel。
1.2 DRM 架構對比 FB 架構優勢
DRM 是目前 Linux 的主流圖形顯示框架,相比於傳統 FB 架構,DRM 允許多個程序同時使用視頻硬件資源,管理多個程序的資源請求、訪問,綜上所述 DRM 更能適應日益更新的顯示硬件,DRM 優勢主要體現:
-
DRM 原生支持多圖層合成,FB 原生不支持多層合成。
-
FB 不支持 VSYNC、DMA-BUF、異步更新和 fence 機制,但 DRM 原生都支持。
-
DRM 統一管理 GPU 和 Display 驅動,讓軟件升級、維護和管理更加方便。
1.3 DRM 圖形顯示框架
DRM 檢測到的每個 GPU 都作爲 DRM 設備,併爲之創建一個設備文件 / dev/dri/cardX 與之連接,從整體架構上來看主要分爲 3 個主要部分:
- libdrm (接口庫)
對底層接口進行封裝,向上層提供通用的 API 接口,主要是對各種 IOCTL 接口進行封裝,便於重用與代碼共享。
- KMS (Kernel Mode Setting)
正常工作時,需要設置顯卡或者圖形適配器的模式,主要體現在以下兩個方面:
更新畫面:顯示 buffer 的切換,多圖層的合成方式控制,以及每個圖層的顯示位置。
設置顯示參數:包括分辨率、刷新率、電源狀態(休眠喚醒)等。
- GEM (Graphics Execution Manager)
提供內存管理方法,主要負責顯示 buffer 的分配和釋放。
圖 1.1 DRM 圖形顯示框架總覽
圖片來源:https://en.wikipedia.org/wiki/Direct_Rendering_Manager#/media/File:DRM_architecture.svg
1.4 DRM 圖形顯示框架涉及元素
本章節介紹 DRM 框架中的一些重點模塊的功能與在顯示鏈路中的作用,下圖爲 APP 調用 DRM 到屏幕顯示的流程框圖。
圖 1.2 DRM 圖形顯示框架框圖
下表對 DRM 中 KMS 和 GEM 兩個模型的不同組件進行概述性說明,輔以高通平臺代碼層級的對應關係說明,以加深架構與流程之間的對應聯繫。
2 、DRM 驅動框架
2.1 DRM 驅動對象介紹
DRM 內部的 Objects 是組成 DRM 框架的核心,下圖中藍色部分爲物理硬件的抽象,棕色部分則爲軟件的抽象,其中 GEM 結構體爲:drm_gem_object,其餘部分位於結構體 drm_mode_object 中.
PS:drm_panel 不屬於 object 範疇,只是爲了降低 LCD 驅動與 encoder 驅動間的耦合,是一堆回調函數集合。
圖 2.1 DRM 核心組件介紹
2.2 DRM 抽象硬件如何關聯 DRM Object
DRM 的 objects 並不難理解,重要的是如何將實際的硬件與這些 object 進行關聯,下面會以 MIPI DSI 接口爲例進行介紹軟件架構與 DRM object 的對應關係。
圖 2.2 典型 MIPI DSI 接口硬件連接圖
圖 2.3 硬件與 DRM Objects 對應圖
其中組件說明:
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 會一直運行,一般不必實施資源清理工作。
本章小結
本文介紹了 DRM 架構的發展歷史、驅動框架以及簡單示例,旨在幫助讀者瞭解 DRM 架構的形成、功能流程實現,DRM 代碼龐大且複雜,想要深入理解它的內涵,最好的辦法就是根據實際需求來進行代碼流程梳理,後續章節也會對該部分進行展開講解。
此外,DRM 架構符合功能日益強大的現代顯示設備,但仍有很多老的設備以及軟件需要 FB 支持,在目前 DRM 框架中,會存在模擬 FB 設備的代碼,參見 drivers/gpu/drm/xxx/drv.c 文件,會在設備目錄下出現:/dev/fb0 。
Reference
1.https://www.kernel.org/doc/html/latest/gpu/index.html
Linux GPU Driver Developer’s Guide
- https://www.kernel.org/doc/html/latest/gpu/drm-kms.html#kms-properties
Kernel Mode Setting (KMS)
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/UQ-IBDp2enOkkBa-XXliIQ