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                        
                    
点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部