1. Linux内核驱动开发概述

1.1 内核模块概念

Linux内核采用模块化设计,允许在运行时动态加载或卸载功能代码片段,这些可独立编译、加载和卸载的代码片段称为内核模块(Kernel Module)。模块机制使得内核功能可以按需扩展,无需重新编译整个内核或重启系统。

核心特点:
  • 动态加载/卸载:使用 insmod / rmmod 命令操作,减少系统停机时间。
  • 独立编译:模块与内核源码树分离开发,通过 Makefile 编译为 .ko 文件。
  • 内核空间运行:模块代码运行在特权级(Ring 0),拥有完全的系统访问权限。
  • 符号导出:通过 EXPORT_SYMBOL 向其他模块提供函数接口。

一个典型的内核模块包含两个基本入口函数:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

static int __init my_driver_init(void)
{
    printk(KERN_INFO "My driver loaded successfully.\n");
    return 0;
}

static void __exit my_driver_exit(void)
{
    printk(KERN_INFO "My driver unloaded.\n");
}

module_init(my_driver_init);
module_exit(my_driver_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Embedded Expert");
MODULE_DESCRIPTION("A sample kernel module for display driver course");
关键宏说明:
__init / __exit 标记函数在初始化/退出后释放内存;module_init / module_exit 注册入口点;MODULE_* 宏提供元数据。

1.2 驱动分类:字符、块、网络

Linux内核将设备驱动划分为三大类,每类对应不同的设备特性和操作接口:

驱动类型 数据访问方式 典型设备 文件接口 关键特性
字符设备 顺序字节流 串口、I2C、SPI、帧缓冲 /dev/xxx 无缓冲、直接读写、支持 open/read/write/ioctl
块设备 随机块访问 硬盘、eMMC、SD卡 /dev/xxx 内核缓冲、支持文件系统、按块寻址
网络设备 数据包收发 以太网、WiFi、CAN socket 接口 无设备节点、通过 net_device 结构管理
注意:显示驱动在Linux中通常以字符设备形式呈现(如帧缓冲 /dev/fb0),但现代DRM/KMS框架使用更复杂的设备模型,底层I2C通信仍属于字符设备范畴。

下图展示了三类驱动在内核中的位置关系与数据流向:

Linux内核驱动分类与数据流向 Linux 内核驱动三大分类 用户空间 (User Space) 系统调用接口 (read / write / ioctl / socket) 字符设备驱动 串口 / I2C / SPI 帧缓冲 / 显示控制器 GPIO / ADC file_operations 结构 块设备驱动 硬盘 / eMMC / SD卡 NVMe / UFS MTD 闪存 block_device_operations 网络设备驱动 以太网 / WiFi CAN / 蓝牙 LoRa / Zigbee net_device 结构 硬件设备 (Hardware) 显示驱动属于 字符设备 + 网络设备混合

1.3 显示驱动在系统中的角色

显示驱动是连接图形输出与物理显示硬件的桥梁,在嵌入式Linux系统中承担以下关键职责:

  1. 帧缓冲管理:分配和管理显存(VRAM),提供应用程序直接写入像素数据的缓冲区。
  2. 显示控制器配置:设置分辨率、刷新率、色彩格式、时序参数(HFP、HBP、VFP、VBP等)。
  3. I2C通信:通过I2C总线与显示面板的EDID、DDC、触摸控制器、背光调节芯片通信。
  4. 背光与电源管理:控制背光亮度、显示面板的上电/下电时序。
  5. DRM/KMS框架集成:现代显示驱动基于Direct Rendering Manager / Kernel Mode Setting,提供统一的显示管理接口。
显示驱动在系统中的位置:
应用程序 → 图形库(Wayland/X11) → DRM/KMS → 显示驱动 → I2C控制器 → 显示面板硬件

下图展示了显示驱动与I2C子系统的协作关系:

显示驱动与I2C通信架构 显示驱动与I2C通信架构 用户应用 (GUI / Wayland / X11) DRM / KMS 框架 显示驱动核心 (Display Driver Core) 帧缓冲管理 | 时序配置 | 色彩格式转换 | 电源管理 I2C 适配器驱动 I2C控制器硬件抽象 显示面板驱动 EDID / DDC / 背光控制 I2C 总线 (I2C Bus) 显示面板硬件 (EDID EEPROM / 触摸IC / 背光IC) 本课程 重点 区域

1.4 显示驱动开发的核心挑战

  • 时序精确性:显示时序参数(H/V同步、前后肩、像素时钟)必须严格匹配面板规格,偏差会导致花屏或不显示。
  • I2C通信可靠性:EDID读取、DDC通信、触摸控制器初始化均依赖I2C,需处理时钟延展、仲裁丢失、ACK/NACK异常。
  • 设备树配置复杂性:显示接口(RGB/LVDS/MIPI DSI/HDMI)的引脚复用、时钟源、复位时序、背光PWM通道均需在设备树中精确描述。
  • 多平台兼容性:同一驱动需适配不同SoC(i.MX、Rockchip、Allwinner、STM32MP等)的显示控制器差异。