一.显示系统概述
linux
内核中包含两类图形显示设备驱动框架:
FB
设备:Framebuffer图形显示框架;DRM
:直接渲染管理器(Direct Rendering Manager
),是linux
目前主流的图形显示框架;
在实际场景中,具体选择哪一种图形设备驱动框架取决于我们自己的业务需求。
Frambebuffer
驱动
Frambebuffer
驱动具有以下特征:
直接控制显卡的帧缓冲区,提供基本的显卡输出功能;
使用一些内核数据结构和API
来管理图形界面,并提供一组接口与用户空间的应用程序进行通信;
相对简单,适合于嵌入式系统或者不需要高性能图形的应用场景。
DRM
驱动
DRM
驱动具有以下特征:
相比FB
(Framebuffer)架构,DRM
更能适应当前日益更新的显示硬件;
提供一种分离的图形驱动架构,将硬件驱动程序、内核模块和用户空间驱动程序进行分离;
支持多个应用程序同时访问显卡,并提供了更丰富的图形功能,例如硬件加速和3D
加速;
提供了一些内核接口,可以让用户空间应用程序与驱动程序进行交互;
支持多显示器(Display
)和多GPU
的配置;
总之,一句话,DRM
是Linux
目前主流的图形显示框架,相比FB
架构,DRM
更能适应当前日益更新的显示硬。尽管FB
退出历史舞台,但是并未将其遗弃,而是集合到DRM
中,供部分嵌入式设备使用。
二.DRM
框架
DRM
子系统的软件架构
DRM
框架从上到下依次为应用程序、libdrm
、DRM driver
、HW
;
(1) 应用程序:上图中并没有画出;应用程序可以直接操纵DRM
的ioctl
进行显示相关操作,后来封装成了libdrm
库,让用户可以更加方便的进行显示控制;
(2) libdrm
:lbdrm
是DRM
框架提供的位于用户空间操作DRM
的库,提供了DRM
驱动的用户空间接口;对底层接口进行封装,向上层应用程序提供通用的API
接口,本质上是对各种ioctl
接口进行封装;
(3) DRM core
:DRM
核心层,由GEM
和KMS
组成;
KMS
:Kernel Mode Setting
,所谓内核显示模式设置,其实说白了就两件事:更新画面和设置显示参数;- 更新画面:显示
buffer
的切换,多图层的合成方式,以及每个图层的显示位置; - 设置显示参数:包括分辨率、刷新率、电源状态(休眠唤醒)等;
- 更新画面:显示
GEM
:Graphic Execution Manager
(图形执行管理器),它提供了一种抽象的显存管理方式,使用户空间应用程序可以更方便地管理显存,而不需要了解底层硬件的细节;- 实际上,在DRM中包含两个内存管理器,
TTM
(Translation Table Manager
)和GEM
(Graphic Execution Manager
),TTM
是第一个开发的DRM
内存管理器,关于TTM
我们就不做过多的介绍了,知道有这么一个东西就好了。
- 实际上,在DRM中包含两个内存管理器,
(4) HW
:硬件设备;
KMS
KMS
主要负责显示相关功能,在DRM
中将其进行抽象,包括:CRTC
、ENCODER
、CONNECTOR
、PLANE
、Framebuffer
、VBLANK
、property
;它们之间的关系如下图所示:
以HDMI
接口为例说明,Soc
内部一般包含一个Display
模块,通过总线连接到HDMI
接口上;
Display
模块对应CRTC
;HDMI
接口对应Connector
;Framebuffer
对应的是显存部分;Plane
是对Framebuffer
进行描述的部分;Encoder
是将像素转化为HDMI
接口所需要的信号,一般Encoder
和Connector
放到一块初始化。
GEM
GEM
主要负责显示buffer
的分配和释放,在DRM
中将其进行抽象,包括:DUMP
、PRIME
、fence
;
三.元素介绍
CRTC:
从Framebuffer
中读取待显示的图像,并按照响应的格式输出给encoder
,其主要承担的作用为
(1)配置适合显示的显示模式、分辨率、刷新率等参数,并输出相应的时序;
(2)扫描Framebuffer
发送到一个或多个显示器;
(3)更新Framebuffer
;
概括下就是,对显示器进行扫描,产生时序信号的模块、负责帧切换、电源控制、色彩调整等等。
Encoder:
编码器。它的作用就是将内存的pixel
像素编码(转换)为显示器所需要的信号。
简单理解就是,如果需要将画面显示到不同的设备(Display Device
)上,需要将画面转化为不同的电信号,例如DVID
、VGA
、YPbPr
、CVBS
、MIPI
、eDP
等。Encoder
和CRTC
之间的交互就是我们所说的Mode Setting
,其中包含了前面提到的色彩模式、还有时序(Timing
)等
Connector:
连接器。它常常对应于物理连接器 (例如VGA
,DVI
, FPD-Link
, HDMI
, DisplayPort
, S-Video
等) ,它不是指物理线。
在DRM
中,Connector
是一个抽象的数据结构,代表连接的显示设备,从Connector
中可以得到当前物理连接的输出设备相关的信息 ;例如连接状态,EDID
数据,DPMS
状态、支持的视频模式等。
Plane:
图层,实际输出的图像是多个图层叠加而成的,比如主图层、光标图层。其中有些图层由硬件加速模块生成,每个CRTC
至少一个plane
;plane
一共有三种,分别是:DRM_PLANE_TYPE_PRIMARY
、DRM_PLANE_TYPE_OVERLAY
、DRM_PLANE_TYPE_CURSOR
。这是配置plane
的三个枚举,标注主图层、覆盖图层、光标图层;
Framebuffer:
Framebuffer
,用于存储单个图层(Plane
)要实现的内容
它是一块内存区域,可以理解为一块画布,驱动程序和应用都能访问它。绘画前需要将它格式化,设定绘制的色彩模式(例如RGB888
,YUV
等)和画布的大小(分辨率)。
Vblank:
软件和硬件的同步机制,RGB
时序中的垂直消影区,软件通常使用硬件VSYNC
来实现。
四.目录结构
linux
内核将DRM
驱动相关的代码都放在drivers/gpu/drm
目录下,这下面的文件还是比较多的,我们大概了解一下即可;
linux-6.3# ls drivers/gpu/drm/ -I "*.o"
amd drm_fbdev_generic.c drm_print.c logicvc
arm drm_fb_dma_helper.c drm_privacy_screen.c Makefile
armada drm_fb_helper.c drm_privacy_screen_x86.c mcde
aspeed drm_file.c drm_probe_helper.c mediatek
ast drm_flip_work.c drm_property.c meson
atmel-hlcdc drm_format_helper.c drm_rect.c mgag200
bridge drm_fourcc.c drm_scatter.c modules.order
built-in.a drm_framebuffer.c drm_self_refresh_helper.c msm
display drm_gem_atomic_helper.c drm_shmem_helper.ko mxsfb
drm_agpsupport.c drm_gem.c drm_shmem_helper.mod nouveau
drm_aperture.c drm_gem_dma_helper.c drm_shmem_helper.mod.c omapdrm
drm_atomic.c drm_gem_framebuffer_helper.c drm_simple_kms_helper.c panel
drm_atomic_helper.c drm_gem_shmem_helper.c drm_syncobj.c panfrost
drm_atomic_state_helper.c drm_gem_ttm_helper.c drm_sysfs.c pl111
drm_atomic_uapi.c drm_gem_vram_helper.c drm_trace.h qxl
drm_auth.c drm_hashtab.c drm_trace_points.c radeon
drm_blend.c drm_internal.h drm_ttm_helper.ko rcar-du
drm_bridge.c drm_ioc32.c drm_ttm_helper.mod rockchip
drm_bridge_connector.c drm_ioctl.c drm_ttm_helper.mod.c scheduler
drm_buddy.c drm_irq.c drm_vblank.c shmobile
drm_bufs.c drm_kms_helper_common.c drm_vblank_work.c solomon
drm_cache.c drm_lease.c drm_vma_manager.c sprd
drm_client.c drm_legacy.h drm_vm.c sti
drm_client_modeset.c drm_legacy_misc.c drm_vram_helper.ko stm
drm_color_mgmt.c drm_lock.c drm_vram_helper.mod sun4i
drm_connector.c drm_managed.c drm_vram_helper.mod.c tegra
drm_context.c drm_memory.c drm_writeback.c tests
drm_crtc.c drm_mipi_dbi.c etnaviv tidss
drm_crtc_helper.c drm_mipi_dsi.c exynos tilcdc
drm_crtc_helper_internal.h drm_mm.c fsl-dcu tiny
drm_crtc_internal.h drm_mode_config.c gma500 ttm
drm_damage_helper.c drm_mode_object.c gud tve200
drm_debugfs.c drm_modes.c hisilicon udl
drm_debugfs_crc.c drm_modeset_helper.c hyperv v3d
drm_displayid.c drm_modeset_lock.c i2c vboxvideo
drm_dma.c drm_of.c i915 vc4
drm_drv.c drm_panel.c imx vgem
drm_dumb_buffers.c drm_panel_orientation_quirks.c ingenic virtio
drm_edid.c drm_pci.c Kconfig vkms
drm_edid_load.c drm_plane.c kmb vmwgfx
drm_encoder.c drm_plane_helper.c lib xen
drm_encoder_slave.c drm_prime.c lima xlnx
其中:
-
drm_drv.c
:DRM core
核心实现; -
drm_gem.c
:提供了GEM
相关的API
;
其中rockchip
为Rockchip
官方的实现代码:
linux-6.3# ls drivers/gpu/drm/rockchip/ -I "*.o"
analogix_dp-rockchip.c inno_hdmi.c rockchip_drm_drv.h rockchip_drm_vop.h
built-in.a inno_hdmi.h rockchip_drm_fb.c rockchip_lvds.c
cdn-dp-core.c Kconfig rockchip_drm_fb.h rockchip_lvds.h
cdn-dp-core.h Makefile rockchip_drm_gem.c rockchip_rgb.c
cdn-dp-reg.c modules.order rockchip_drm_gem.h rockchip_rgb.h
cdn-dp-reg.h rk3066_hdmi.c rockchip_drm_vop2.c rockchip_vop2_reg.c
dw_hdmi-rockchip.c rk3066_hdmi.h rockchip_drm_vop2.h rockchip_vop_reg.c
dw-mipi-dsi-rockchip.c rockchip_drm_drv.c rockchip_drm_vop.c rockchip_vop_reg.h