1、课程导论:显示子系统全景图、DRM/KMS框架简介、设备树基础概念、开发板选型与资料准备
各位同学,欢迎来到《嵌入式Linux显示驱动移植与设备树配置实战》的第一章。
做嵌入式Linux开发,尤其是显示驱动这块,很多人一开始会觉得无从下手。为什么?因为显示子系统涉及的东西太多了——从最底层的硬件接口(比如MIPI DSI、HDMI、LVDS),到内核里的DRM/KMS框架,再到上层的应用层(比如Wayland、X11),最后还要跟设备树打交道。说实话,我早年刚接触时也懵过一阵子。
但别怕。这一章,我们就先把整个显示子系统的“地图”画出来。你知道了全局,后面再深入每个细节,心里就有底了。
1.1 显示子系统全景图
嵌入式Linux的显示子系统,说白了就是一条“数据流水线”。应用程序生成图像数据,经过层层处理,最终在屏幕上显示出来。这条流水线大致可以分为三层:
- 应用层:比如Qt、GTK、Wayland Compositor。它们负责绘制窗口、处理用户交互。
- 内核层:核心就是DRM/KMS框架。它管理显存、控制显示控制器、处理显示时序。
- 硬件层:包括GPU(图形处理器)、Display Controller(显示控制器)、Encoder(编码器)、Connector(连接器)、Panel(面板)。
我习惯把这三层的关系想象成一个“工厂流水线”:应用层是“设计部门”,画好图纸;内核层是“生产调度”,安排资源、控制机器;硬件层就是“车间里的机器”,负责实际输出。
下面这张图,就是整个显示子系统的核心结构。你把它看懂了,后面学起来会轻松很多。
1.2 DRM/KMS框架简介
DRM(Direct Rendering Manager)和KMS(Kernel Mode Setting)是Linux内核中显示子系统的核心框架。我当年第一次看到这两个缩写时,还以为是什么高深莫测的东西。其实说白了:
- DRM:负责管理显存、同步访问、提供用户空间接口(比如
/dev/dri/card0)。它让多个程序可以安全地共享显示资源。 - KMS:负责设置显示模式——分辨率、刷新率、像素时钟这些。它直接操作显示控制器硬件。
DRM/KMS框架里,有几个核心概念你必须记住:
| 概念 | 说明 | 类比 |
|---|---|---|
| CRTC | 显示控制器,负责生成显示时序、扫描显存输出 | 流水线上的“传送带” |
| Plane | 图像层,可以叠加多个图层(如视频层、UI层) | 流水线上的“物料托盘” |
| Encoder | 编码器,将数字信号转为特定接口格式(如HDMI、LVDS) | 流水线上的“转换器” |
| Connector | 物理连接器,代表实际的显示接口 | 流水线的“出口” |
| FB (Framebuffer) | 帧缓冲,存储一帧图像数据的内存区域 | 流水线上的“产品” |
我的经验:调试显示驱动时,最常用的命令就是 modetest。它可以直接操作DRM/KMS,查看当前有哪些CRTC、Plane、Connector。我习惯在移植完驱动后,先用 modetest -M <driver_name> 验证框架是否正常工作。
1.3 设备树基础概念
设备树(Device Tree)是嵌入式Linux中描述硬件信息的“说明书”。它告诉内核:你的板子上有哪些外设、它们怎么连接、需要什么配置。
为什么需要设备树?因为ARM架构不像x86那样有自动枚举硬件的机制。你想想看,一个SoC可以搭配不同的板子,外设连接方式千差万别。如果没有设备树,每换一块板子就得重新编译内核——这谁受得了?
设备树的核心语法很简单,就是一堆节点和属性:
/dts-v1/;
/ {
model = "My Board";
compatible = "vendor,my-board";
chosen {
stdout-path = &uart0;
};
lcd_panel: display@0 {
compatible = "my,lcd-panel";
pinctrl-0 = <&lcd_pins>;
backlight = <&backlight>;
port {
panel_in: endpoint {
remote-endpoint = <&display_out>;
};
};
};
};
这里有几个关键点:
compatible:驱动匹配的关键字。内核通过它找到对应的驱动程序。reg:寄存器地址或设备地址。pinctrl:引脚复用配置。port/endpoint:描述设备之间的数据连接关系。
避坑指南:我曾经在一个项目里,因为设备树里 compatible 字符串写错了一个字母,导致驱动死活加载不上。查了两天才发现是拼写问题。所以,写设备树时一定要仔细核对 compatible 的值,最好从驱动源码里复制过来。
1.4 开发板选型与资料准备
选开发板,说白了就是选SoC。不同的SoC,显示控制器、GPU、接口都不一样。我个人建议初学者从这几款入手:
| 开发板 | SoC | 显示接口 | 适合场景 |
|---|---|---|---|
| Raspberry Pi 4 | BCM2711 | HDMI 2.0, DSI | 入门、社区资源丰富 |
| i.MX8M Mini EVK | i.MX8M Mini | MIPI DSI, LVDS, HDMI | 工业级、文档齐全 |
| STM32MP157 | STM32MP157 | MIPI DSI, LTDC | 教学、双核A7+M4 |
| RK3399 | Rockchip RK3399 | HDMI, MIPI DSI, eDP | 高性能、Android/Linux双用 |
选好板子后,你需要准备以下资料:
- SoC数据手册(Datasheet):显示控制器、时钟、GPIO的寄存器描述。
- 参考手册(Reference Manual):比数据手册更详细,包含编程指南。
- 原理图(Schematic):知道显示接口连到了SoC的哪些引脚。
- 内核源码:建议用LTS版本,比如5.10或6.1。
- 设备树绑定文档:内核源码里
Documentation/devicetree/bindings/display/目录下。
我的习惯:拿到一块新板子,我第一件事就是看原理图,找到显示接口的引脚连接。然后对照SoC数据手册,确认这些引脚对应的功能。最后再去看内核里已有的设备树文件,看看有没有现成的配置可以参考。这样一套下来,心里就有数了。
嗯,第一章的内容就到这里。你先把这张“地图”记在脑子里,后面我们就要开始动手了——从编译内核、配置设备树,到点亮第一块屏幕。