2. DRM 开发环境搭建

搭建一套可用的 DRM/KMS 开发环境是学习显示子系统的第一步。本章将引导你完成从内核源码获取、内核配置、编译到 QEMU 模拟环境搭建的全流程。一个稳定、可复现的开发环境能让你在后续章节中专注于 DRM 框架本身,而非环境问题。

2.1 内核源码获取

推荐使用 LTS(长期支持)版本 的内核源码进行学习,例如 v6.1.y 或 v6.6.y 系列。这些版本稳定且文档齐全。

获取方式 命令/URL 说明
Git 克隆(推荐) git clone --depth=1 -b v6.6.y git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git 只拉取最新提交,节省带宽和时间
完整 Git 仓库 git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 包含所有历史,适合深度调试
直接下载 tarball https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.tar.xz 无需 Git,适合一次性编译
提示: 建议在 Linux 发行版(如 Ubuntu 22.04/24.04)上进行开发。如果使用 Windows,请启用 WSL2 或使用虚拟机。

2.2 内核配置选项:DRM 相关

DRM 子系统通过 Kconfig 机制进行配置。以下是与显示输出直接相关的核心选项,必须正确启用。

Device Drivers --->
  Graphics support --->
    <*> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)  --->
      [*]   Enable legacy drivers (DRI1, etc.)
      <*>   DRM driver for Virtual Machine (QEMU/virtio)  <-- 用于 QEMU 模拟
      <*>   DRM driver for bochs/qvga
      <*>   DRM Support for bochs dispi vga interface (qemu stdvga)
      [*]   Enable legacy fbdev support for your modesetting driver
      Console display driver support --->
        <*>   Framebuffer Console support
        [*]     Map the console to the primary display device
配置项 含义 学习阶段建议
CONFIG_DRM DRM 核心框架,所有 DRM 驱动的基础 必须开启(y)
CONFIG_DRM_VIRTIO_GPU QEMU virtio-gpu 设备驱动,用于虚拟化显示 必须开启(y)
CONFIG_DRM_BOCHS Bochs VGA 兼容驱动,QEMU 默认 VGA 后端 建议开启(y)
CONFIG_FB_CFB_FILLRECT 帧缓冲加速函数,提升控制台性能 建议开启(y)
CONFIG_DRM_DEBUG_MM DRM 内存管理调试信息 调试时开启
注意: 如果使用 QEMU 的 -vga std 或 -vga virtio,必须确保对应的 DRM 驱动被编译进内核(y)或作为模块(m)。模块方式需要在启动后手动 modprobe。

2.3 编译内核与模块

配置完成后,执行以下步骤编译内核。这里假设使用 x86_64 架构。

  1. 生成默认配置(基于当前架构):
    make defconfig
  2. 应用自定义配置:
    make menuconfig 或 make nconfig,然后按 2.2 节设置 DRM 选项。
  3. 编译内核和模块:
    make -j$(nproc) bzImage modules
  4. 安装模块(可选,用于本地运行):
    sudo make modules_install
  5. 安装内核(可选,用于本地运行):
    sudo make install

编译完成后,内核镜像位于 arch/x86_64/boot/bzImage,模块位于 lib/modules/<kernel-version>/。

关键指标: 首次编译内核(含 DRM 驱动)在 8 核 CPU 上大约需要 10-20 分钟。后续增量编译通常只需 1-3 分钟。

2.4 QEMU 模拟环境搭建

QEMU 是学习 DRM/KMS 的最佳平台。它允许你在不依赖真实硬件的情况下,模拟多种显示设备,并支持 GDB 调试内核。

2.4.1 安装 QEMU

# Ubuntu/Debian
sudo apt install qemu-system-x86 qemu-kvm libvirt-daemon-system

# Fedora
sudo dnf install qemu-system-x86 qemu-kvm

2.4.2 创建根文件系统

使用 Buildroot 或 Busybox 制作一个最小的根文件系统(rootfs)。这里以 Buildroot 为例:

# 下载 Buildroot
git clone https://git.buildroot.net/buildroot
cd buildroot

# 配置(选择 x86_64 架构,并开启 dropbear 用于 SSH)
make qemu_x86_64_defconfig
make menuconfig  # 可选:添加 strace, gdb 等调试工具

# 编译(生成 output/images/rootfs.ext2)
make -j$(nproc)

2.4.3 启动 QEMU 并验证 DRM

使用以下命令启动 QEMU,挂载编译好的内核和根文件系统:

qemu-system-x86_64 \
  -kernel /path/to/linux/arch/x86_64/boot/bzImage \
  -append "root=/dev/sda console=ttyS0 nokaslr" \
  -drive file=/path/to/buildroot/output/images/rootfs.ext2,format=raw,if=ide \
  -net nic,model=virtio -net user \
  -vga virtio \
  -m 2G \
  -smp 2 \
  -nographic

启动后,在 QEMU 控制台内执行以下命令验证 DRM 是否正常工作:

# 查看 DRM 设备
ls /dev/dri/
# 输出应包含 card0 和 renderD128

# 查看 DRM 驱动信息
cat /sys/kernel/debug/dri/0/name
# 输出类似: virtio_gpu

# 查看当前显示模式
cat /sys/class/drm/card0-modes
# 输出类似: 1024x768 1280x800 ...
提示: 如果使用 -vga std,则驱动为 bochs-drm;如果使用 -vga virtio,则驱动为 virtio-gpu。两者都是学习 DRM 框架的优秀起点。

2.5 开发环境架构总览

下图展示了整个开发环境的组件关系与数据流:

DRM 开发环境架构图 DRM 开发环境架构总览 主机开发环境(Ubuntu 22.04 / WSL2) 内核源码 + GCC 交叉编译工具链 + Buildroot QEMU 虚拟机(x86_64) -vga virtio / -vga std 模拟显示设备:virtio-gpu / bochs-drm Linux 内核(v6.6.y) DRM 核心框架 (CONFIG_DRM=y) virtio-gpu / bochs-drm 驱动 帧缓冲控制台 (fbcon) 用户空间程序 modetest / kmscube / weston / Xorg 说明:所有组件均在主机上运行,QEMU 提供硬件模拟,内核提供 DRM 服务,用户空间程序进行验证

2.6 常见问题与排查

问题现象 可能原因 解决方案
/dev/dri/ 目录为空 DRM 驱动未加载或未编译进内核 检查 CONFIG_DRM_VIRTIO_GPU 或 CONFIG_DRM_BOCHS 是否设置为 y
QEMU 启动后黑屏 帧缓冲控制台未启用或显示设备参数错误 确保 CONFIG_FB_CFB_FILLRECT 和 CONFIG_FRAMEBUFFER_CONSOLE 开启
内核编译报错 缺少依赖库或工具链版本不匹配 安装 build-essential、flex、bison、libncurses-dev
QEMU 无法挂载 rootfs 内核未开启 ext2 文件系统支持 开启 CONFIG_EXT2_FS 或使用 initramfs
避坑指南: 不要在生产环境的内核上直接修改 DRM 驱动代码进行实验。始终使用 QEMU 虚拟机进行开发和调试,避免因内核崩溃导致主机系统不稳定。