Rust编写PCIe字符设备驱动:QEMU到物理硬件的工程实战
引言:当Rust遇见内核硬件驱动
Rust for Linux项目自2021年合并进内核邮件列表以来,已从实验性质演变为2025-2026年内核子系统的重要组成部分。截至Linux 6.9/6.10,Rust驱动框架已支持PCI、Platform、GPIO等多种总线类型,社区贡献的样品驱动覆盖NVMe、GPU DRM、网络PHY等场景。然而,网上大多数教程停留在"Hello World"级别的模块加载,缺乏一个完整的、可运行到物理硬件的实战案例。
本文将填补这一空白:从零开始用Rust编写一个完整的PCIe字符设备驱动。我们将经历枚举BAR空间、配置MSI-X中断、分配DMA一致缓冲区、实现mmap用户空间映射、ioctl控制接口的全过程。代码在QEMU中可验证,架构上可直接迁移到真实PCIe硬件。这不是玩具代码——这是一条将Rust借用检查器带入硬件交互级编程的工程路径。
环境准备:Rust for Linux交叉编译环境
内核配置要求
# 确认内核支持Rust
cd /path/to/linux-6.x
grep CONFIG_RUST .config
# CONFIG_RUST=y
# CONFIG_RUSTC_BINDING_GENERATOR=y
# CONFIG_RUST_LIB_TEST=n
# 工具链检查
rustc --version
# rustc 1.82 (需-nightly用于内核某些feature)
bindgen --version
# bindgen 0.70
项目结构
pci-rust-demo/
├── Cargo.toml
├── Makefile
├── build.rs
├── src/
│ ├── lib.rs # 入口与类型定义
│ ├── pci.rs # PCIe设备发现与BAR映射
│ ├── dma.rs # DMA分配与映射
│ ├── irq.rs # MSI-X中断处理
│ ├── char_dev.rs # cdev与文件操作
│ └── ioctl.rs # 用户空间控制接口
├── scripts/
│ └── qemu-run.sh # QEMU启动脚本(含igb/virtio-pci平台)
└── README.md
Cargo.toml配置如下,关键依赖是kernel crate(来自Rust for Linux官方subtree):
[package]
name = "pci_rust_demo"
version = "0.1.0"
edition = "2024"
[dependencies]
kernel = { git = "https://github.com/Rust-for-Linux/linux.git", branch = "rust-next", features = ["module_inject"] }
核心数据结构:设备上下文的全生命周期
// src/lib.rs
#![no_std]
#![allow(unused)]
mod pci;
mod dma;
mod irq;
mod char_dev;
mod ioctl;
use kernel::prelude::*;
use kernel::pci::DeviceId;
module! {
type: PciRustDemo,
name: "pci_rust_demo",
author: "ybb.press",
description: "Rust PCIe character device driver demo",
license: "GPL",
}
/// 设备上下文 — 贯穿整个驱动的生命周期
pub(crate) struct DeviceContext {
/// PCIe BAR0 映射的MMIO寄存器基址
bar0: Device

发表评论 取消回复