Skip to content

驱动程序 (Device Driver)

一、驱动程序概述

什么是驱动程序

设备驱动程序 (Device Driver),简称驱动,是操作系统中专门负责与硬件设备通信的软件组件。

本质:操作系统的"翻译官"——把硬件的物理特性和操作方式抽象成统一的接口,让上层应用无需关心硬件细节。

核心职责:

  • 初始化硬件:上电后让设备进入工作状态
  • 数据传输:在 CPU/内存与设备间搬运数据
  • 中断处理:响应硬件中断,完成相应操作
  • 错误处理:检测和处理设备故障
  • 电源管理:设备的休眠/唤醒
  • 提供接口:向内核或用户空间暴露统一 API

为什么需要驱动

应用层
   ↓ 系统调用 (open/read/write/ioctl)
内核通用层 (VFS/网络栈/...)
   ↓ 驱动接口
设备驱动层 (具体硬件驱动)
   ↓ 寄存器、总线协议
硬件设备
  • 隔离硬件差异:不同厂商的硬件实现不同,但对上层提供统一接口
  • 保护系统:防止应用直接操作硬件,保障安全
  • 简化应用开发:应用只调用标准 API,无需了解硬件细节
  • 支持热插拔:动态加载/卸载设备支持

二、设备分类

1. 按访问方式 (Linux 视角)

类型 访问单位 是否可寻址 典型设备
字符设备 字符流 否(顺序) 键盘、鼠标、串口、打印机、终端
块设备 数据块 是(随机) 硬盘、SSD、U 盘、SD 卡
网络设备 报文/帧 - 网卡、WiFi、蓝牙(伪字符)

2. 按设备归属

类型 特点
系统设备 主板集成(CPU 内置、南桥)
外部设备 通过总线连接的扩展设备
虚拟设备 不存在的物理硬件,由软件模拟
伪设备 /dev/null、/dev/zero、/dev/random

3. 按 IO 模型

  • 轮询 (Polling):CPU 主动查询设备状态
  • 中断 (Interrupt):硬件主动通知 CPU
  • DMA (Direct Memory Access):数据搬运不经过 CPU
  • MMIO (Memory-Mapped I/O):把设备寄存器映射到内存地址空间
  • PMIO (Port I/O):用专门的 I/O 端口地址访问(x86)

三、Linux 驱动架构

1. Linux 内核设备模型

Linux 2.6 引入统一的设备模型,核心概念:

Bus (总线)
  ├── Device (设备)
  │     ├── Driver (驱动)
  │     └── Class (类)
  └── ...
  • Bus:总线(PCI、USB、I2C、SPI、Platform)
  • Device:具体的硬件设备
  • Driver:设备的驱动
  • Class:同类设备的抽象(网卡、输入设备等)
  • Subsystem:子系统(网络、输入、块、声音)

关键结构 (Linux 内核源码 include/linux/):

struct bus_type { ... };
struct device { ... };
struct device_driver { ... };
struct class { ... };

2. 设备文件系统 (/sys)

  • /syssysfs 文件系统的挂载点
  • 暴露内核对象和设备信息到用户空间
  • 可读、可写、可监控
  • udev 配合,实现自动设备管理
# 查看 PCI 设备
ls /sys/bus/pci/devices/

# 查看块设备
ls /sys/block/

# 查看 USB 设备
ls /sys/bus/usb/devices/

# 读设备属性
cat /sys/class/net/eth0/speed

3. 设备节点 (/dev)

  • /devdevtmpfsdevfs 的挂载点
  • 每个设备对应一个设备文件:
  • 字符设备:c 开头
  • 块设备:b 开头
  • 主设备号 + 次设备号标识唯一设备
$ ls -l /dev/sda
brw-rw---- 1 root disk 8, 0 /dev/sda
#  ↑ 块设备  主=8  次=0

$ ls -l /dev/null
crw-rw-rw- 1 root root 1, 3 /dev/null
#  ↑ 字符设备  主=1  次=3

4. Linux 驱动模块

内核模块 (Kernel Module):

  • 编译成 .ko 文件 (Kernel Object)
  • 可动态加载到内核,无需重启
  • 大多数 Linux 驱动都是模块
# 加载模块
sudo insmod mydriver.ko
sudo modprobe mydriver     # 自动解决依赖

# 卸载模块
sudo rmmod mydriver

# 查看已加载模块
lsmod

# 模块信息
modinfo mydriver

模块结构 (Hello World 驱动):

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

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

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

module_init(mydriver_init);
module_exit(mydriver_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple driver");

Makefile:

obj-m += mydriver.o
KDIR := /lib/modules/$(shell uname -r)/build
all:
    make -C $(KDIR) M=$(PWD) modules
clean:
    make -C $(KDIR) M=$(PWD) clean

5. 内核与驱动的接口

  • file_operations:字符设备接口(.open/.read/.write/.ioctl/.release)
  • block_device_operations:块设备接口
  • net_device_ops:网络设备接口
  • probe/remove:PCI/USB 设备的热插拔回调
  • file_operations.ioctlunlocked_ioctl:新版字符设备 ioctl

四、Linux 驱动子系统

1. 字符设备驱动

特点:以字节为单位读写,通常不支持随机访问。

核心结构: struct file_operations

static struct file_operations my_fops = {
    .owner   = THIS_MODULE,
    .open    = my_open,
    .read    = my_read,
    .write   = my_write,
    .release = my_release,
    .unlocked_ioctl = my_ioctl,
};

// 注册字符设备
static int __init my_init(void) {
    alloc_chrdev_region(&devno, 0, 1, "mydev");
    cdev_init(&cdev, &my_fops);
    cdev_add(&cdev, devno, 1);
    // ...
}

典型字符设备:

  • 终端 (/dev/tty)
  • 串口 (/dev/ttyS*)
  • 键盘 (/dev/input/event*)
  • 鼠标
  • 打印机 (/dev/lp*)
  • 随机数 (/dev/random, /dev/urandom)
  • 帧缓冲 (/dev/fb*)
  • 摄像头 (/dev/video*)

2. 块设备驱动

特点:以块 (Block) 为单位读写,512 字节或 4KB,支持随机访问。

核心结构: struct block_device_operations

static struct block_device_operations my_bdops = {
    .open    = my_open,
    .release = my_release,
    .getgeo  = my_getgeo,
};

关键概念:

  • bio (Block I/O):块 I/O 请求的数据结构
  • request_queue:请求队列
  • I/O 调度器:CFQ (已废弃)、Deadline、BFQ、Kyber、None (多队列 NVMe)
  • 页缓存 (Page Cache):内核的磁盘缓存
  • 文件系统接口:VFS → 文件系统 (Ext4 等) → 块设备驱动

典型块设备:硬盘、SSD、SD 卡、U 盘、RAID 设备、Loop 设备 (/dev/loop*)

3. 网络设备驱动

特点:以数据包 (Packet) 为单位,通过 Socket 接口访问。

核心结构: struct net_device

static const struct net_device_ops my_netdev_ops = {
    .ndo_open       = my_open,
    .ndo_stop       = my_stop,
    .ndo_start_xmit = my_start_xmit,
    .ndo_set_mac_address = my_set_mac,
};

// 注册网络设备
register_netdev(ndev);

关键概念:

  • sk_buff (Socket Buffer):网络数据包结构
  • NAPI (New API):中断 + 轮询混合模式,提高高负载下性能
  • RSS / RPS / RFS:多核 CPU 的网络包分发
  • TSO / GSO / LRO:大段卸载,降低 CPU 占用
  • VLAN / 桥接 / Bonding:网络虚拟化

典型网络设备:有线网卡、WiFi、蓝牙、CAN 总线、PPP

4. 输入子系统 (Input Subsystem)

统一处理所有输入设备(键盘、鼠标、触摸屏、游戏手柄)。

核心结构: struct input_dev

input_dev = input_allocate_device();
input_dev->name = "My Device";
input_set_capability(input_dev, EV_KEY, KEY_A);
input_register_device(input_dev);

// 上报事件
input_report_key(input_dev, KEY_A, 1);
input_sync(input_dev);

事件类型 (EV_):

  • EV_KEY:按键
  • EV_REL:相对坐标(鼠标)
  • EV_ABS:绝对坐标(触摸屏)
  • EV_MSC:杂项

5. 声音子系统 (ALSA)

ALSA (Advanced Linux Sound Architecture):Linux 声音系统。

核心结构: struct snd_pcm_ops, struct snd_card

用户空间:alsa-libPulseAudioPipeWire

典型设备:声卡、HDMI 音频、USB 音频设备

6. USB 子系统

USB 协议栈:

应用层
  ↓
USB 设备驱动 (具体设备:鼠标/U盘/打印机)
  ↓
USB 核心 (USB Core)
  ↓
USB 主机控制器驱动 (Host Controller Driver: EHCI/XHCI)
  ↓
PCI 总线

关键结构: struct usb_driver, struct usb_device

USB 类别 (bInterfaceClass):

  • 03h:HID (Human Interface Device) - 键鼠
  • 08h:大容量存储 - U 盘
  • 09h:Hub
  • 0Eh:视频
  • 0Bh:智能卡
  • FFh:厂商自定义

7. PCI / PCIe 子系统

PCI (Peripheral Component Interconnect):最常见的扩展总线。

关键结构: struct pci_driver, struct pci_device_id

驱动注册:

static struct pci_device_id my_ids[] = {
    { PCI_DEVICE(0x1234, 0x5678) },  // 厂商 ID + 设备 ID
    { 0, }
};
MODULE_DEVICE_TABLE(pci, my_ids);

static struct pci_driver my_driver = {
    .name     = "my_driver",
    .id_table = my_ids,
    .probe    = my_probe,
    .remove   = my_remove,
};
module_pci_driver(my_driver);

PCIe 版本与速度:

PCIe 版本 单通道速率 x16 带宽
1.0 2.5 GT/s 4 GB/s
2.0 5 GT/s 8 GB/s
3.0 8 GT/s 16 GB/s
4.0 16 GT/s 32 GB/s
5.0 32 GT/s 64 GB/s
6.0 64 GT/s 128 GB/s

8. 平台设备 (Platform Device)

用于片上系统 (SoC) 的内置设备:嵌入式芯片、ARM SoC 上的 UART、I2C、SPI、GPIO。

通过设备树 (Device Tree) 描述:arch/arm/boot/dts/*.dts

9. I2C / SPI 驱动

I2C / SPI:嵌入式最常用的两种串行总线。

  • I2C:低速(400 kHz / 1 MHz / 3.4 MHz),2 线(SCL/SDA)
  • SPI:高速(几十 MHz),4 线(MOSI/MISO/SCK/CS)

典型 I2C 设备:EEPROM、传感器、RTC、LED 控制器

典型 SPI 设备:Flash、传感器、显示屏、ADC/DAC

10. 其他重要子系统

  • GPIO:通用输入输出
  • PWM:脉冲宽度调制
  • IIO (Industrial I/O):传感器(加速度计、陀螺仪、温湿度)
  • Media (V4L2):视频采集
  • FB / DRM/KMS:显示
  • RTC:实时时钟
  • Watchdog:看门狗
  • HWmon:硬件监控(温度/电压/风扇)
  • Regulator:电源管理
  • Pin Control:引脚复用

五、Linux 内核驱动关键机制

1. 中断处理

  • 顶半部 (Top Half):紧急,关中断,只做最少工作
  • 底半部 (Bottom Half):延后,开中断
  • Softirq(软中断):静态,数量固定(10 个)
  • Tasklet(任务队列):基于 softirq
  • Workqueue(工作队列):进程上下文,可睡眠
  • Threaded IRQ:中断线程化

2. 同步机制

  • 自旋锁 (Spinlock):忙等,适合短临界区
  • 互斥锁 (Mutex):可睡眠,适合长临界区
  • 信号量 (Semaphore):资源计数
  • RCU (Read-Copy-Update):读写并发,极高性能
  • completion:完成量
  • seqlock:顺序锁
  • 内存屏障 (Memory Barrier):mb(), rmb(), wmb()

3. 内存管理

  • kmalloc / kfree:内核动态分配
  • vmalloc / vfree:虚拟连续但物理不连续
  • GFP flags:GFP_KERNELGFP_ATOMIC
  • DMA:dma_map_single / dma_unmap_single
  • ioremap:把物理地址映射到内核虚拟地址
  • mmap:把设备内存映射到用户空间
  • DMA-BUF:共享 DMA 缓冲区
  • CMA (Contiguous Memory Allocator):大块连续内存
  • devm_* 自动资源管理(随设备自动释放)

4. 电源管理

  • Suspend / Resume:pm_runtime_*
  • Runtime PM:运行时电源管理
  • Wakeup / Wake lock
  • CPU Idle:CPU 空闲状态
  • CPUFreq:CPU 调频
  • Devfreq:设备调频
  • Thermal:温度管理

5. DMA

DMA (Direct Memory Access):无需 CPU 参与的数据搬运。

类型:

  • Coherent DMA:一致,CPU 和设备都看得到
  • Streaming DMA:单向,流式
  • Scatter-Gather:分散-聚集,一次 DMA 处理多个不连续缓冲区
  • Bus Mastering:设备自己当总线主控

DMA 引擎 API:统一的不同硬件 DMA 控制器接口

6. 设备树 (Device Tree, DT)

为什么需要:ARM 架构硬件差异大,无法像 x86 那样硬编码。

DTS (Device Tree Source):硬件描述文件

示例:

/ {
    soc {
        uart0: serial@1000 {
            compatible = "vendor,uart";
            reg = <0x1000 0x100>;
            interrupts = <5>;
            clocks = <&clk_uart>;
        };
    };
};

compatible 字符串匹配驱动。

7. ACPI

ACPI (Advanced Configuration and Power Interface):x86 平台的硬件描述和电源管理。

  • 比 DT 更老,更复杂
  • 提供电源管理、热管理、配置
  • 现代 Linux 同时支持 DT (ARM) 和 ACPI (x86)

六、内核与用户空间交互

1. ioctl

ioctl (Input/Output Control):用户空间对设备下发特殊命令。

// 用户空间
int fd = open("/dev/mydevice", O_RDWR);
int val;
ioctl(fd, MY_CMD_GET, &val);

// 内核驱动
static long my_ioctl(struct file *f, unsigned int cmd, unsigned long arg) {
    switch (cmd) {
        case MY_CMD_GET:
            copy_to_user((int *)arg, &val, sizeof(val));
            break;
        case MY_CMD_SET:
            copy_from_user(&val, (int *)arg, sizeof(val));
            break;
    }
    return 0;
}

2. sysfs 属性

暴露设备参数到 /sys:

static ssize_t show_value(struct device *dev,
                         struct device_attribute *attr, char *buf) {
    return sprintf(buf, "%d\n", my_value);
}
static DEVICE_ATTR(value, 0444, show_value, NULL);
device_create_file(dev, &dev_attr_value);

3. procfs / debugfs

  • /proc:进程和系统信息
  • /sys:设备模型
  • /debug (debugfs):开发调试

双向通信,广泛用于网络配置、路由表、防火墙。

5. UIO (Userspace I/O)

让用户空间程序直接访问设备寄存器: - 适合高性能、低延迟场景 - 例子:网络加速、信号处理 - 工具:uio_pci_generic

6. VFIO

更强大的用户空间 I/O: - 支持 IOMMU,安全隔离 - 用于 GPU 直通、RDMA - 虚拟化关键技术

方式 适合
字符设备 数据流、大块数据
netlink 配置、异步通知
ioctl 一次性命令、参数设置
sysfs 单一属性、监控

七、用户空间驱动框架

1. libpci

直接操作 PCI 配置空间(用户空间)。

2. libusb

用户空间 USB 驱动,绕过内核 USB 栈。

3. SPDK (Storage Performance Development Kit)

Intel 推出的用户态 NVMe 驱动,绕过内核,极致性能。

4. DPDK (Data Plane Development Kit)

用户态网络驱动,绕过内核网络栈,极低延迟。

5. RDMA / libibverbs

远程直接内存访问,内核旁路。

6. XDP (eXpress Data Path)

内核 eBPF 实现的网络数据面,比传统快一个数量级。

7. io_uring

异步 I/O,共享环形缓冲区,极少系统调用。

8. eBPF

内核沙箱程序,可动态注入网络、跟踪、安全策略,无需重启。


八、Linux 内核驱动与硬件生态

1. 驱动来源

驱动来源 特点
内核自带 (in-tree) 随 Linux 内核发布,质量高
厂商 out-of-tree 厂商提供,与内核解耦
闭源 (binary blob) NVIDIA、博通等,仅二进制
开源社区 (DKMS) 动态编译模块,匹配内核
用户态驱动 libusb、SPDK、DPDK

2. 主要硬件厂商驱动支持

厂商 开源策略 例子
Intel 几乎全开源 e1000e、ixgbe、I915、I40e
AMD 全开源 amdgpu、k10temp、kvm-amd
NVIDIA 闭源 + 开源 nvidia.ko (闭源)、nouveau (开源)
博通 Broadcom 部分闭源 BCM 无线网卡、SoC
Realtek 多数开源 r8169、rtl8xxx 系列
高通 Qualcomm 部分闭源,内核中较多 ath10k (无线)
联发科 MTK 开源 mt76 (无线)
华为 开源 + 自研 HNS 网卡、Hisilicon 驱动
寒武纪 / 燧原 / 壁仞 部分开源 AI 加速器
Marvell 闭源为主 网卡、SSD 控制器
Mellanox 全开源 mlx5 (RDMA 主力)

3. 主流硬件类别驱动示例

类别 驱动名 厂商
Intel 网卡 e1000e、igb、ixgbe、i40e Intel
Realtek 网卡 r8169、r8125 Realtek
NVMe SSD nvme 通用
AHCI/SATA ahci 通用
NVIDIA GPU nvidia、nouveau NVIDIA
AMD GPU amdgpu、radeon AMD
Intel GPU i915、xe Intel
USB xhci、ehci、uhci、ohci 通用
WiFi (Intel) iwlwifi Intel
WiFi (Qualcomm) ath10k、ath11k、ath12k Qualcomm
蓝牙 btusb、btintel 通用
声卡 snd_hda_intel Intel
输入设备 atkbd (键盘)、psmouse (鼠标) 通用

九、主流驱动开发框架

1. 字符设备框架 (cdev)

适合自定义字符设备,前面已详述。

2. misc device (杂项设备)

简化字符设备注册:

static struct miscdevice my_misc = {
    .minor = MISC_DYNAMIC_MINOR,
    .name  = "mydevice",
    .fops  = &my_fops,
};
misc_register(&my_misc);

3. platform_driver

SoC 平台设备驱动:

static struct platform_driver my_driver = {
    .probe  = my_probe,
    .remove = my_remove,
    .driver = {
        .name = "my-device",
        .of_match_table = my_of_match,
    },
};
module_platform_driver(my_driver);

4. PCI / PCIe 驱动

见前文。

5. USB 驱动

static struct usb_driver my_driver = {
    .name     = "my_usb",
    .probe    = my_probe,
    .disconnect = my_disconnect,
    .id_table = my_id_table,
};
module_usb_driver(my_driver);

6. 网络设备 (NAPI)

高吞吐网卡必备:

// 中断处理:接收数据
static irqreturn_t my_interrupt(int irq, void *dev_id) {
    napi_schedule(&priv->napi);
    return IRQ_HANDLED;
}

// poll 循环
static int my_poll(struct napi_struct *napi, int budget) {
    int work_done = 0;
    while (work_done < budget) {
        // 处理数据包
    }
    napi_complete(napi);
    return work_done;
}

7. 设备树匹配

static const struct of_device_id my_of_match[] = {
    { .compatible = "vendor,my-device" },
    { },
};
MODULE_DEVICE_TABLE(of, my_of_match);

8. ACPI 匹配

static const struct acpi_device_id my_acpi_match[] = {
    { "MYD0001", 0 },
    { },
};

9. 高级框架

  • IIO (Industrial I/O):传感器
  • V4L2 (Video4Linux2):摄像头/视频
  • ALSA SoC (ASoC):嵌入式声卡
  • MMC/SD/SDIO:存储卡
  • MIPI DSI/CSI:显示屏/摄像头(移动端)
  • RPMSG:多核通信
  • VFIO / vDPA / vhost:虚拟化 I/O
  • Rust 内核驱动(Linux 6.1+):Rust 写驱动

十、驱动调试

1. 打印

printk(KERN_DEBUG "debug: val=%d\n", val);
dev_dbg(dev, "device debug\n");
dynamic_pr_debug("...");

2. 内核日志

  • dmesg:查看内核日志
  • journalctl -k:systemd 日志
  • loglevel:/proc/sys/kernel/printk

3. 调试器

  • kgdb:内核 gdb,双机调试
  • kdb:内核自带简单调试器
  • crash:分析 crash dump
  • KASAN / KMSAN / UBSan:内存/未定义行为检测
  • KCSAN:数据竞争检测
  • syzkaller:模糊测试

4. 性能分析

  • perf:Linux 性能分析神器
  • ftrace:函数追踪
  • bpftrace:eBPF 高级追踪
  • strace:系统调用追踪
  • bcc / bpftool:eBPF 工具
  • ltrace:库调用追踪

5. 硬件调试

  • 示波器 / 逻辑分析仪:看波形
  • JTAG / OpenOCD:硬件级调试
  • PCIe 分析仪

6. 锁调试

  • lockdep:锁依赖检测,自动发现死锁
  • lock_stat:锁竞争统计
  • spinlock debug

十一、驱动安全

1. 常见漏洞

  • 缓冲区溢出:用户输入没检查
  • 整数溢出:算术运算溢出
  • UAF (Use-After-Free):释放后使用
  • TOCTOU (Time-of-check to time-of-use):检查后使用之间被改
  • 竞态条件:并发访问

2. 内核安全机制

  • KASLR:内核地址空间随机化
  • SMEP / SMAP:禁止内核执行/访问用户内存
  • Stack Protector:栈金丝雀
  • CFI (Control Flow Integrity):控制流完整性
  • KASAN:内核地址消毒
  • Hardening:编译选项加固 (-fstack-protector-strong, -D_FORTIFY_SOURCE=2)
  • Rust 驱动:编译期保证内存安全
  • LSM (Linux Security Module):SELinux、AppArmor、Landlock

3. 编写安全驱动的最佳实践

  • 所有用户输入都要校验(copy_from_user 一定要检查)
  • devm_* 函数自动管理资源
  • 避免竞态:合理使用锁
  • 最小权限:只做必要的事
  • 参考内核已有驱动:模仿成熟代码

十二、驱动开发学习路径

入门

  1. C 语言熟练、Linux 基本使用
  2. 学习 Linux 内核基本概念(进程、内存、文件系统)
  3. 读 LDD3 (Linux Device Drivers, 3rd Edition)
  4. 写一个简单的字符设备驱动 (Hello World)
  5. 编译、加载、调试模块

进阶

  1. 字符/块/网络设备驱动
  2. 中断、并发、内存管理
  3. PCI、USB、I2C、SPI 设备
  4. 设备树、ACPI
  5. 电源管理、DMA

高级

  1. 内核子系统源码阅读
  2. 性能优化
  3. 安全加固
  4. 参与开源驱动项目
  5. Rust 内核驱动

推荐资源

  • 《Linux Device Drivers》(LDD3) - 经典教材(免费)
  • 《Linux Kernel Development》(Robert Love)
  • 《深入理解 Linux 内核》
  • Linux 内核源码:kernel.org
  • LWN.net:深度技术文章
  • 内核邮件列表:LKML
  • elinux.org(嵌入式 Linux)
  • kernelnewbies.org(新手社区)

十三、驱动生态与重要项目

1. 内核源码组织

drivers/
├── block/        # 块设备
├── char/         # 字符设备
├── net/          # 网络设备
├── input/        # 输入设备
├── sound/        # 声音
├── usb/          # USB
├── pci/          # PCI
├── i2c/          # I2C
├── spi/          # SPI
├── gpio/         # GPIO
├── mmc/          # SD/MMC
├── mtd/          # 闪存
├── ata/          # SATA/ATA
├── scsi/         # SCSI
├── nvme/         # NVMe
├── gpu/          # GPU (drm 子系统)
├── media/        # 摄像头 (V4L2)
├── tty/          # 终端
├── net/          # 网络
├── bluetooth/    # 蓝牙
├── hwmon/        # 硬件监控
├── regulator/    # 电源管理
├── thermal/      # 温度
├── watchdog/     # 看门狗
├── pinctrl/      # 引脚控制
├── clk/          # 时钟
├── firmware/     # 固件加载
└── ...

2. 内核维护者 (Subsystem Maintainers)

每个子系统都有自己的维护者团队,负责 merge 代码到自己的 tree。

3. 关键驱动项目

项目 描述
Linux 内核 主线驱动,质量最高
DRM/KMS (GPU) 显示和 GPU
Mesa3D 用户空间 GPU 驱动(开源)
NVIDIA 闭源驱动 性能最佳,游戏/AI 主力
Nouveau NVIDIA 开源(性能差)
Intel I915/Xe Intel GPU 开源
AMD amdgpu AMD GPU 开源(质量好)
Linux VFIO 用户态直通
SPDK Intel 用户态存储驱动
DPDK Intel 用户态网络驱动
RDMA 内核和用户态 RDMA
Open vSwitch 软件定义网络
wg-quick WireGuard VPN
DRBD 分布式块设备复制

4. 驱动更新方式

  • 主线内核:每 2-3 个月一版,所有驱动都更新
  • 稳定内核:stable 分支,只修 bug
  • LTS 内核:长期支持(2~6 年),企业首选
  • 发行版内核:Ubuntu、Debian、RHEL 各自维护
  • 厂商 out-of-tree:在主线外,自己发行
  • DKMS:自动重编译匹配新内核

十四、驱动与硬件接口标准

1. 总线标准

总线 速度 用途
PCIe 64 GB/s (6.0) 通用扩展(高速)
USB 20 Gbps (4) 外设通用
Thunderbolt 40-100 Gbps 高性能外接
SATA 6 Gbps 存储
SAS 22.5 Gbps 企业存储
NVMe 14 GB/s (5) SSD(基于 PCIe)
I2C 5 Mbps 嵌入式低速
SPI 几十 MHz 嵌入式中速
UART 1 Mbps 串口调试
CAN 1 Mbps 汽车、工业
I2S - 音频
SDIO - SD 卡、WiFi 模组
MIPI - 移动端(DSI/CSI)

2. 硬件接口标准

  • VESA:显示器
  • HDMI / DP:音视频
  • NVMe:SSD
  • ACPI:x86 电源管理
  • DT:ARM 硬件描述
  • USB-IF:USB 规范
  • PCI-SIG:PCI 规范
  • MIPI Alliance:移动端

十五、虚拟化中的驱动

1. 虚拟机驱动

  • virtio:半虚拟化标准接口,性能好
  • virtio-net / virtio-blk / virtio-scsi
  • vhost-net / vhost-scsi:内核态 virtio 加速
  • VFIO:PCI 设备直通
  • SR-IOV:单根 I/O 虚拟化,网卡/GPU 物理功能虚拟出多个虚拟功能

2. 容器中的驱动

  • cgroup:资源限制(CPU、内存、I/O)
  • namespace:资源隔离
  • device cgroup:限制容器能访问的设备
  • eBPF:安全、监控、网络
  • FUSE:用户空间文件系统

3. 用户态驱动框架

  • VFIO + DPDK:用户态高性能网络
  • VFIO + SPDK:用户态高性能存储
  • UIO:通用用户态 I/O
  • XDP:eBPF 网络数据面

十六、特殊驱动场景

1. 嵌入式 Linux 驱动

  • 特点:硬件资源少,SoC 多样
  • 设备树:必备
  • U-Boot:Bootloader
  • Buildroot / Yocto / OpenWrt:构建系统
  • cross-compile:交叉编译

2. 实时 Linux 驱动

  • PREEMPT_RT:实时内核补丁
  • Xenomai:双内核实时
  • RTAI:实时硬件抽象
  • cyclictest:测试实时性

3. 异构计算驱动

  • GPU 驱动:CUDA、ROCm、OpenCL
  • FPGA 驱动:OpenCL、Vitis
  • NPU/TPU 驱动:昇腾 CANN、寒武纪

4. AI 加速器驱动

  • 主流:NVIDIA (CUDA)、AMD (ROCm)、Intel (oneAPI)、华为昇腾、寒武纪、海光
  • 开源:MIOpen、oneDNN
  • 框架:PyTorch、TensorFlow、MindSpore、PaddlePaddle

5. RDMA 驱动

  • Mellanox mlx5:InfiniBand / RoCE 主力
  • Intel i40e / ice:RoCE
  • 应用:高性能存储 (NVMe-oF)、HPC、低延迟通信

6. DPU (Data Processing Unit)

  • NVIDIA BlueField:ARM + ConnectX 网卡
  • Intel IPU:基础设施处理单元
  • Marvell OCTEON
  • 趋势:卸载存储、网络、安全到 DPU,释放 CPU

十七、核心要点速记

  • 驱动 = OS 与硬件的翻译官
  • 3 大设备类型:字符设备(字节流)、块设备(块)、网络设备(包)
  • Linux 设备模型:Bus → Device → Driver → Class
  • 设备文件:/dev/sda(块)、/dev/null(字符)
  • 设备属性:/sys/...(sysfs)
  • 模块加载:insmod/modprobe/rmmod/lsmod
  • 关键结构:file_operationsblock_device_operationsnet_device_opspci_driver
  • 设备树 (DT):ARM 平台硬件描述
  • ACPI:x86 平台硬件描述
  • probe/remove:PCI/USB 热插拔回调
  • 中断机制:顶半部 + 底半部(softirq/tasklet/workqueue)
  • 同步:自旋锁、互斥锁、RCU、内存屏障
  • DMA:Coherent、Streaming、SG
  • 用户态驱动:libusb、SPDK、DPDK、VFIO、XDP、io_uring
  • 安全:KASLR、SMEP/SMAP、KASAN、Rust
  • 调试:printk、kgdb、perf、ftrace、bpftrace、lockdep
  • 驱动来源:内核自带、厂商 out-of-tree、DKMS、用户态
  • LDD3 是经典入门书
  • Linux 内核驱动 90%+ 是开源的
  • 驱动开发需要懂硬件协议、操作系统、C 语言
  • 现代趋势:Rust 驱动、DPU 卸载、用户态驱动、eBPF