团队博客: 汽车电子社区
1. 显示子系统概述
Linux显示子系统是操作系统中负责图形显示和用户界面的核心组件,它构成了Linux图形栈的基础架构。从底层的硬件抽象到上层的用户界面渲染,显示子系统提供了一个完整、高效、可扩展的图形处理解决方案。
1.1 系统架构概览
Linux显示子系统采用分层架构设计,主要包括以下层次:
- 硬件抽象层(HAL):直接与显卡硬件交互,提供基础的硬件访问能力
- 内核显示子系统:包含DRM(Direct Rendering Manager)和KMS(Kernel Mode Setting)
- 用户空间图形库:包括Mesa、DirectFB等图形渲染库
- 窗口系统和合成器:如X11、Wayland、GNOME Shell等
- 应用层:图形应用程序和工具
1.2 核心组件
显示子系统的核心组件包括:
1. DRM(Direct Rendering Manager):内核级的直接渲染管理器
2. KMS(Kernel Mode Setting):内核模式设置,负责显示模式配置
3. Framebuffer:帧缓冲设备,提供基础的图形显示能力
4. GPU驱动:各种GPU设备的内核驱动程序
5. 用户空间驱动:如NVIDIA、AMD等厂商的用户空间驱动组件
2. 软件架构深度分析
2.1 整体架构图
2.2 核心架构组件详解
2.2.1 DRM(Direct Rendering Manager)
DRM是Linux内核中的直接渲染管理器,它为用户空间程序提供对GPU硬件的直接访问能力。DRM的主要职责包括:
- GPU内存管理:管理GPU专用的内存空间
- 命令缓冲区管理:处理GPU命令的提交和执行
- 同步机制:提供CPU和GPU之间的同步原语
- 权限控制:确保只有授权的进程可以访问GPU资源
DRM架构采用模块化设计,支持多种GPU类型:
2.2.2 GPU内存管理架构
GPU内存管理是DRM的核心功能,涉及显存、系统内存和共享内存的管理:
2.2.3 GPU同步机制
GPU同步机制确保CPU和GPU之间的正确协调:
2.2.4 命令缓冲区管理
命令缓冲区是GPU执行的核心机制:
2.2.5 KMS(Kernel Mode Setting)
KMS是内核模式设置系统,负责管理显示设备的状态配置。KMS的主要功能包括:
- 显示模式设置:配置分辨率、刷新率等显示参数
- CRTC管理:控制CRT控制器,负责实际的像素输出
- 连接器管理:管理显示输出连接器(HDMI、DP、VGA等)
- 帧缓冲管理:管理显示缓冲区和平面配置
KMS的核心数据结构和工作机制:
// include/drm/drm_mode_object.h
struct drm_mode_object {
uint32_t id;
uint32_t type;
struct drm_mode_object *properties;
struct drm_device *dev;
};
// include/drm/drm_crtc.h
struct drm_crtc {
struct drm_device *dev;
struct list_head head;
/* 当前状态 */
struct drm_display_mode mode;
struct drm_framebuffer *fb;
int x, y;
/* 配置信息 */
struct drm_crtc_helper_funcs *helper_private;
const struct drm_crtc_funcs *funcs;
/* 平面列表 */
struct drm_plane *primary;
struct drm_plane *cursor;
/* 属性 */
struct drm_object_properties properties;
/* 统计信息 */
struct drm_crtc_crc crc;
spinlock_t crc_lock;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_entry;
#endif
};
// include/drm/drm_connector.h
struct drm_connector {
struct drm_device *dev;
struct list_head head;
/* 连接器信息 */
int connector_type;
int connector_type_id;
char name[32];
/* 显示信息 */
struct drm_display_info display_info;
/* 状态和模式 */
enum drm_connector_status status;
struct drm_display_mode *display_mode;
struct list_head modes;
/* 回调函数 */
const struct drm_connector_funcs *funcs;
struct drm_connector_helper_funcs *helper_private;
/* 属性 */
struct drm_object_properties properties;
uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
int encoder_ids_count;
/* DPMS状态 */
int dpms;
};
2.3 GPU驱动架构
Linux支持多种GPU架构,每种GPU都有专门的驱动实现:
2.3.1 NVIDIA驱动架构
NVIDIA采用专有的驱动架构,包含内核模块和用户空间组件:
2.3.2 AMD驱动架构
AMD采用开源驱动策略,主要使用AMDGPU驱动:
2.3.3 Intel驱动架构
Intel的GPU驱动完全开源,集成在内核中:
3. 调用流程深度分析
3.1 显示初始化流程
Linux系统启动时,显示子系统的初始化是一个复杂的过程,涉及多个组件的协同工作。
3.2 图形渲染流程
图形应用程序的渲染流程涉及多个层次的转换和优化:
3.3 模式设置流程
显示模式的设置是KMS的核心功能,涉及CRTC、连接器和帧缓冲的协调:
3.4 页面翻转流程
页面翻转(Page Flip)是实现无撕裂显示的关键技术:
3.5 内存管理流程
GPU内存管理是显示子系统性能的关键因素:
4. 源码深度分析
4.1 DRM核心源码分析
4.1.1 DRM设备初始化
DRM设备的初始化过程在drivers/gpu/drm/drm_drv.c中实现:
// drivers/gpu/drm/drm_drv.c
int drm_dev_init(struct drm_device *dev, struct drm_driver *driver,
struct device *parent)
{
int ret;
/* 初始化DRM设备结构 */
dev->driver = driver;
dev->dev = parent;
/* 初始化锁和同步机制 */
mutex_init(&dev->mode_config.lock);
mutex_init(&dev->master_mutex);
spin_lock_init(&dev->event_lock);
spin_lock_init(&dev->filelist_lock);
spin_lock_init(&dev->clientlist_lock);
spin_lock_init(&dev->ctxlist_lock);
/* 初始化列表头 */
INIT_LIST_HEAD(&dev->filelist);
INIT_LIST_HEAD(&dev->clientlist);
INIT_LIST_HEAD(&dev->ctxlist);
INIT_LIST_HEAD(&dev->vblank_event_list);
/* 初始化工作队列 */
dev->wq = alloc_ordered_workqueue("drm_%s", 0, driver->name);
if (!dev->wq)
return -ENOMEM;
/* 初始化模式配置 */
ret = drm_mode_config_init(dev);
if (ret)
goto err_wq;
/* 初始化内存管理 */
ret = drm_gem_init(dev);
if (ret)
goto err_mode_config;
/* 初始化VBLANK */
ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
if (ret)
goto err_gem;
/* 创建调试文件系统 */
ret = drm_debugfs_init(dev);
if (ret)
goto err_vblank;
return 0;
err_vblank:
drm_vblank_cleanup(dev);
err_gem:
drm_gem_destroy(dev);
err_mode_config:
drm_mode_config_cleanup(dev);
err_wq:
destroy_workqueue(dev->wq);
return ret;
}
EXPORT_SYMBOL(drm_dev_init);
4.1.2 模式配置初始化
模式配置的初始化在drivers/gpu/drm/drm_mode_config.c中实现:
// drivers/gpu/drm/drm_mode_config.c
int drm_mode_config_init(struct drm_device *dev)
{
struct drm_mode_config *config = &dev->mode_config;
/* 初始化配置参数 */
config->min_width = 0;
config->min_height = 0;
config->max_width = 8192;
config->max_height = 8192;
config->funcs = NULL;
/* 初始化回调函数 */
config->fb_base = (unsigned long)dev->mode_config.fb_base;
config->prefer_shadow = 0;
config->cursor_width = 64;
config->cursor_height = 64;
/* 初始化列表 */
INIT_LIST_HEAD(&config->crtc_list);
INIT_LIST_HEAD(&config->connector_list);
INIT_LIST_HEAD(&config->encoder_list);
INIT_LIST_HEAD(&config->property_list);
INIT_LIST_HEAD(&config->blob_list);
INIT_LIST_HEAD(&config->plane_list);
/* 初始化ID管理 */
mutex_init(&config->idr_mutex);
idr_init(&config->crtc_idr);
idr_init(&config->connector_idr);
idr_init(&config->encoder_idr);
/* 创建属性 */
drm_mode_create_standard_properties(dev);
/* 初始化模式配置锁 */
mutex_init(&config->mutex);
return 0;
}
EXPORT_SYMBOL(drm_mode_config_init);
4.1.3 CRTC管理
CRTC(Cathode Ray Tube Controller)是显示控制的核心组件:
// include/drm/drm_crtc.h
struct drm_crtc *drm_crtc_create(struct drm_device *dev,
const struct drm_crtc_funcs *funcs,
const struct drm_crtc_helper_funcs *helper_funcs)
{
struct drm_crtc *crtc;
int ret;
/* 分配CRTC结构 */
crtc = kzalloc(sizeof(*crtc), GFP_KERNEL);
if (!crtc)
return ERR_PTR(-ENOMEM);
/* 初始化CRTC结构 */
crtc->dev = dev;
crtc->funcs = funcs;
crtc->helper_private = helper_funcs;
/* 分配ID */
ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
if (ret) {
kfree(crtc);
return ERR_PTR(ret);
}
/* 初始化属性 */
drm_object_attach_property(&crtc->base,
dev->mode_config.property_active, 0);
drm_object_attach_property(&crtc->base,
dev->mode_config.property_mode_id, 0);
/* 添加到设备列表 */
list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
/* 初始化CRC支持 */
if (dev->mode_config.funcs->crc_init)
dev->mode_config.funcs->crc_init(crtc);
return crtc;
}
EXPORT_SYMBOL(drm_crtc_create);
4.2 GPU驱动源码分析
4.2.1 Intel i915驱动分析
Intel i915驱动是Intel集成显卡的内核驱动实现:
// drivers/gpu/drm/i915/i915_drv.c
static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct intel_device_info *device_info;
struct drm_i915_private *dev_priv;
int ret;
/* 分配私有数据结构 */
dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
if (!dev_priv)
return -ENOMEM;
/* 初始化设备信息 */
device_info = (struct intel_device_info *)ent->driver_data;
intel_device_info_runtime_init(device_info);
/* 设置设备私有数据 */
dev_priv->dev = pdev;
dev_priv->info = device_info;
/* 初始化PCI设备 */
ret = pcim_enable_device(pdev);
if (ret)
return ret;
/* 设置PCI掩码 */
ret = pcim_iomap_regions(pdev,
~(intel_region_map[INTEL_REGION_STOLEN].base |
intel_region_map[INTEL_REGION_LMEM].base),
"i915");
if (ret)
return ret;
/* 初始化DRM设备 */
ret = i915_driver_load(pdev, ent);
if (ret)
return ret;
return 0;
}
// drivers/gpu/drm/i915/i915_gem.c
int i915_gem_init(struct drm_i915_private *dev_priv)
{
struct i915_ggtt *ggtt = &dev_priv->ggtt;
int ret;
/* 初始化全局图形翻译表 */
ret = i915_ggtt_init_hw(dev_priv);
if (ret)
goto err_ggtt;
/* 初始化GPU上下文 */
ret = intel_engines_init(dev_priv);
if (ret)
goto err_engines;
/* 初始化内存管理 */
ret = i915_gem_contexts_init(dev_priv);
if (ret)
goto err_contexts;
/* 初始化工作队列 */
INIT_WORK(&dev_priv->gem.idle_work, i915_gem_idle_work_handler);
INIT_WORK(&dev_priv->gem.retire_work, i915_gem_retire_work_handler);
/* 初始化VM */
ret = i915_ggtt_enable_hw(dev_priv);
if (ret)
goto err_vm;
return 0;
err_vm:
i915_gem_contexts_fini(dev_priv);
err_contexts:
intel_engines_cleanup(dev_priv);
err_engines:
i915_ggtt_cleanup_hw(dev_priv);
err_ggtt:
return ret;
}
4.2.2 AMDGPU驱动分析
AMD GPU驱动是AMD GPU的开源驱动实现:
// drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
static int amdgpu_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct amdgpu_device *adev;
struct drm_device *dev;
int ret;
/* 分配AMD GPU设备结构 */
adev = kzalloc(sizeof(*adev), GFP_KERNEL);
if (!adev)
return -ENOMEM;
/* 初始化设备结构 */
dev = adev_to_drm(adev);
dev->pdev = pdev;
dev->dev = &pdev->dev;
adev->dev = dev;
adev->pdev = pdev;
adev->family = ent->driver_data;
/* 初始化PCI设备 */
ret = pcim_enable_device(pdev);
if (ret)
goto err_free;
/* 设置PCI掩码 */
ret = pcim_iomap_regions(pdev, 0xff, "amdgpu");
if (ret)
goto err_free;
/* 初始化AMDGPU设备 */
ret = amdgpu_device_init(adev, ent);
if (ret)
goto err_free;
/* 注册DRM设备 */
ret = drm_dev_register(dev, ent->driver_data);
if (ret)
goto err_device_fini;
return 0;
err_device_fini:
amdgpu_device_fini(adev);
err_free:
kfree(adev);
return ret;
}
// drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
int amdgpu_device_init(struct amdgpu_device *adev,
const struct pci_device_id *ent)
{
int r, i;
/* 初始化互斥锁 */
mutex_init(&adev->cmn_sem);
mutex_init(&adev->firmware.mutex);
mutex_init(&adev->pm.mutex);
/* 初始化工作队列 */
adev->wq = alloc_ordered_workqueue("amdgpu", 0);
if (!adev->wq)
return -ENOMEM;
/* 初始化MC(内存控制器) */
r = amdgpu_mc_init(adev);
if (r)
goto failed_wq;
/* 初始化MMIO(内存映射I/O) */
r = amdgpu_device_ip_early_init(adev);
if (r)
goto failed_mc;
/* 初始化IP块 */
r = amdgpu_device_ip_init(adev);
if (r)
goto failed_early_init;
/* 初始化GPUVM */
r = amdgpu_gpu_vm_init(adev);
if (r)
goto failed_ip;
/* 初始化Firmware */
r = amdgpu_device_ip_late_init(adev);
if (r)
goto failed_vm;
/* 初始化CP(命令处理器) */
r = amdgpu_ib_ring_tests(adev);
if (r)
goto failed_late_init;
return 0;
failed_late_init:
amdgpu_device_ip_late_fini(adev);
failed_vm:
amdgpu_gpu_vm_fini(adev);
failed_ip:
amdgpu_device_ip_fini(adev);
failed_early_init:
amdgpu_device_ip_early_fini(adev);
failed_mc:
amdgpu_mc_fini(adev);
failed_wq:
destroy_workqueue(adev->wq);
return r;
}
4.3 用户空间图形库源码分析
4.3.1 Mesa 3D驱动
Mesa是Linux上的主要OpenGL实现,支持多种GPU:
// src/mesa/drivers/dri/i965/intel_screen.c
static struct pipe_screen *
intel_create_screen(struct drm_device *dev)
{
struct intel_screen *intel;
/* 分配屏幕结构 */
intel = calloc(1, sizeof(*intel));
if (!intel)
return NULL;
/* 初始化DRM设备 */
intel->fd = drm_fd;
intel->dev = dev;
/* 获取设备信息 */
if (!intel_get_device_info(intel))
goto err_free;
/* 初始化上下文 */
if (!intel_init_context(intel))
goto err_free;
/* 创建管道屏幕 */
intel->base = intel_create_pipe_screen(intel);
if (!intel->base)
goto err_free;
return intel->base;
err_free:
free(intel);
return NULL;
}
// src/mesa/drivers/dri/i965/intel_batchbuffer.c
void
intel_batchbuffer_emit_render(struct intel_batchbuffer *batch,
const struct intel_render_state *state)
{
/* 准备渲染状态 */
intel_batchbuffer_begin(batch);
/* 发送状态设置 */
intel_batchbuffer_emit_state(batch, state);
/* 发送绘制命令 */
intel_batchbuffer_emit_draw(batch);
/* 提交批处理 */
intel_batchbuffer_end(batch);
/* 提交到GPU */
intel_batchbuffer_flush(batch);
}
4.3.2 Vulkan驱动
Vulkan是新一代的图形API,提供了更直接的硬件访问:
// src/vulkan/wsi/wsi_common.c
VkResult wsi_create_swapchain(VkDevice device_h,
const VkSwapchainCreateInfoKHR *create_info,
const struct wsi_swapchain_funcs *funcs,
VkSwapchainKHR *swapchain_h)
{
struct wsi_device *wsi_device = wsi_device_from_handle(device_h);
struct wsi_swapchain *swapchain;
VkResult result;
/* 分配交换链结构 */
swapchain = vk_alloc(&wsi_device->alloc,
sizeof(*swapchain),
8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!swapchain)
return VK_ERROR_OUT_OF_HOST_MEMORY;
/* 初始化交换链 */
swapchain->device = wsi_device;
swapchain->funcs = funcs;
swapchain->image_count = create_info->minImageCount;
swapchain->format = create_info->imageFormat;
/* 创建图像 */
result = funcs->create_images(swapchain, create_info);
if (result != VK_SUCCESS)
goto err_free;
/* 创建信号量 */
result = funcs->create_semaphores(swapchain);
if (result != VK_SUCCESS)
goto err_images;
*swapchain_h = wsi_swapchain_to_handle(swapchain);
return VK_SUCCESS;
err_images:
funcs->destroy_images(swapchain);
err_free:
vk_free(&wsi_device->alloc, swapchain);
return result;
}
5. 性能优化与调试
5.1 性能优化策略
5.1.1 GPU调度优化
GPU调度器负责优化命令执行的顺序和时机:
// drivers/gpu/drm/scheduler/gpu_scheduler.c
int drm_sched_job_init(struct drm_sched_job *job,
struct drm_sched_entity *entity,
void *owner)
{
struct drm_gpu_scheduler *sched = entity->rq->sched;
/* 初始化任务结构 */
job->entity = entity;
job->s_fence = drm_sched_fence_create(entity, owner);
if (!job->s_fence)
return -ENOMEM;
job->sched = sched;
job->id = atomic64_inc_return(&sched->job_id_counter);
/* 添加到实体队列 */
spin_lock(&entity->rq_lock);
list_add_tail(&job->list, &entity->job_list);
atomic64_inc(&entity->rq->sched->num_jobs);
spin_unlock(&entity->rq_lock);
return 0;
}
EXPORT_SYMBOL(drm_sched_job_init);
static void drm_sched_job_run(struct work_struct *work)
{
struct drm_gpu_scheduler *sched = container_of(work,
struct drm_gpu_scheduler,
work_run_job);
struct drm_sched_job *job;
struct drm_sched_fence *s_fence;
int r;
/* 从队列获取任务 */
spin_lock(&sched->job_list_lock);
job = list_first_entry_or_null(&sched->pending_list,
struct drm_sched_job, list);
if (!job) {
spin_unlock(&sched->job_list_lock);
return;
}
list_del_init(&job->list);
spin_unlock(&sched->job_list_lock);
s_fence = job->s_fence;
/* 执行任务 */
atomic_inc(&sched->hw_rq_count);
r = sched->ops->run_job(job);
/* 处理结果 */
if (r) {
drm_sched_fence_set_error(s_fence, r);
} else {
dma_fence_signal(&s_fence->finished);
}
atomic_dec(&sched->hw_rq_count);
wake_up(&sched->job_scheduled);
}
5.1.2 内存管理优化
高效的GPU内存管理是性能的关键:
// drivers/gpu/drm/drm_gem.c
int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
{
struct drm_file *priv = filp->private_data;
struct drm_device *dev = priv->minor->dev;
struct drm_gem_object *obj;
int ret;
/* 查找GEM对象 */
obj = drm_gem_object_lookup(dev, priv, vma->vm_pgoff);
if (!obj)
return -ENOENT;
/* 设置映射属性 */
vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
/* 建立映射 */
ret = obj->funcs->mmap(obj, vma);
if (ret)
goto out_unref;
/* 更新引用计数 */
drm_gem_object_put(obj);
return 0;
out_unref:
drm_gem_object_put(obj);
return ret;
}
EXPORT_SYMBOL(drm_gem_mmap);
5.2 调试工具和方法
5.2.1 调试文件系统
DRM提供了丰富的调试接口:
// drivers/gpu/drm/drm_debugfs.c
int drm_debugfs_init(struct drm_device *dev)
{
struct drm_minor *minor = dev->primary;
struct dentry *root, *ent;
/* 创建调试根目录 */
root = debugfs_create_dir("drm", minor->debugfs_root);
if (IS_ERR(root))
return PTR_ERR(root);
/* 创建设备文件 */
ent = debugfs_create_file("name", 0444, root, dev, &drm_name_fops);
if (IS_ERR(ent))
goto err;
ent = debugfs_create_file("drivers", 0444, root, dev, &drm_drivers_fops);
if (IS_ERR(ent))
goto err;
ent = debugfs_create_file("clients", 0444, root, dev, &drm_clients_fops);
if (IS_ERR(ent))
goto err;
/* 创建GPU特定调试文件 */
if (dev->driver->debugfs_init)
dev->driver->debugfs_init(minor, root);
return 0;
err:
debugfs_remove_recursive(root);
return PTR_ERR(ent);
}
5.2.2 性能监控
性能监控是优化的重要工具:
// drivers/gpu/drm/drm_atomic.c
int drm_atomic_check_only(struct drm_atomic_state *state)
{
struct drm_crtc_state *crtc_state;
struct drm_connector_state *conn_state;
struct drm_plane_state *plane_state;
struct drm_crtc *crtc;
struct drm_connector *conn;
struct drm_plane *plane;
int i, ret;
/* 检查所有CRTC状态 */
for_each_crtc_in_state(state, crtc, crtc_state, i) {
ret = drm_atomic_crtc_check(crtc, crtc_state);
if (ret)
return ret;
}
/* 检查所有连接器状态 */
for_each_connector_in_state(state, conn, conn_state, i) {
ret = drm_atomic_connector_check(conn, conn_state);
if (ret)
return ret;
}
/* 检查所有平面状态 */
for_each_plane_in_state(state, plane, plane_state, i) {
ret = drm_atomic_plane_check(plane, plane_state);
if (ret)
return ret;
}
return 0;
}
6. 总结与展望
Linux显示子系统是一个复杂而精密的软件架构,它成功地统一了不同厂商GPU的接口,为用户空间提供了稳定、高效的图形处理能力。通过对软件架构、调用流程和源码的深度分析,我们可以看到以下几个关键特点:
6.1 架构优势
1. 模块化设计:DRM框架提供了良好的抽象层次,使得不同GPU驱动可以采用统一的接口
2. 分层架构:从硬件抽象到用户空间的清晰分层,便于维护和扩展
3. 标准化接口:通过标准化的API和协议,确保了不同组件之间的互操作性
4. 高性能设计:通过直接内存访问、命令缓冲区等技术实现了高性能图形处理
6.2 技术挑战
1. 硬件多样性:需要支持不同厂商、不同架构的GPU硬件
2. 性能优化:在保证兼容性的同时实现最佳性能
3. 安全考虑:确保GPU访问的安全性和隔离性
4. 功耗管理:在移动设备上实现高效的功耗控制
6.3 未来发展方向
1. AI加速:集成机器学习硬件加速支持
2. 云计算:优化虚拟化环境中的图形处理性能
3. 实时渲染:提高实时图形渲染的质量和效率
4. 异构计算:更好地集成CPU、GPU和其他加速器
Linux显示子系统作为操作系统的重要组成部分,将继续在桌面、移动、云计算等领域发挥关键作用,为用户提供优秀的图形体验和计算能力。随着硬件技术的不断发展和用户需求的不断提升,显示子系统也将不断演进和完善。

1341

被折叠的 条评论
为什么被折叠?



