[AI] [Linux] 教我用rust写一个GPIO驱动

用 Rust 为 Linux 内核写一个 GPIO 驱动

每一颗 LED 第一次亮起的瞬间,背后都是一段代码战胜了混沌。

当你用 Rust 写下第一个 GPIO 驱动,你不只是在控制一个引脚的高低电平------你是在用一门拒绝段错误的语言,亲手触碰硬件世界最原始的脉搏。没有垃圾回收器的庇护,没有运行时的缓冲,只有你、编译器、和那一根细细的铜线。

编译通过的那一刻,灯亮了。那是你写的。

本文基于 Linux 7.0 + RISC-V + QEMU,带你从零完成一个 Rust GPIO 内核模块。


环境准备

1. 安装工具链

bash 复制代码
# Clang/LLVM(RISC-V 上 Rust 内核支持强制要求 Clang,GCC 不行)
sudo apt install -y clang lld llvm libclang-dev

# RISC-V 交叉编译器(编译 C 部分仍需要)
sudo apt install -y gcc-riscv64-linux-gnu

# Rust 组件
rustup component add rust-src
cargo install --locked bindgen-cli
export PATH="$HOME/.cargo/bin:$PATH"

踩坑 1HAVE_RUST 在 RISC-V 上依赖 CC_IS_CLANG,用 GCC 会导致 CONFIG_RUST 灰掉无法启用,必须用 LLVM=1

2. 验证 Rust 支持就绪

bash 复制代码
cd /path/to/linux
make ARCH=riscv LLVM=1 rustavailable

无任何报错才能继续。


配置内核

bash 复制代码
# 生成 RISC-V 默认配置
make ARCH=riscv LLVM=1 defconfig

# 启用 Rust
scripts/config --enable CONFIG_RUST
scripts/config --enable CONFIG_IKCONFIG_PROC   # 可选:允许读 /proc/config.gz

# 同步配置
make ARCH=riscv LLVM=1 olddefconfig

# 确认
grep "CONFIG_RUST=" .config   # 应输出 CONFIG_RUST=y

编写驱动

1. 创建源文件

drivers/gpio/rust_gpio_demo.rs

rust 复制代码
// SPDX-License-Identifier: GPL-2.0

//! Rust GPIO demo driver

use kernel::prelude::*;

module! {
    type: RustGpioDemo,
    name: "rust_gpio_demo",
    authors: ["Your Name"],        // 注意:是 authors(数组)不是 author
    description: "A simple GPIO demo driver in Rust",
    license: "GPL",
}

struct RustGpioDemo;

impl kernel::Module for RustGpioDemo {
    fn init(_module: &'static ThisModule) -> Result<Self> {
        pr_info!("Rust GPIO demo driver loaded!\n");
        Ok(RustGpioDemo)
    }
}

impl Drop for RustGpioDemo {
    fn drop(&mut self) {
        pr_info!("Rust GPIO demo driver unloaded!\n");
    }
}

与 C 驱动的对比:

概念 Rust C
模块声明 module! {} MODULE_LICENSE() 等宏
初始化 impl kernel::Module module_init()
清理 impl Drop(自动调用) module_exit()
资源释放 RAII,自动 手动 free/release
日志 pr_info!() pr_info()

2. 注册到构建系统

drivers/gpio/Kconfig ,在 endmenu 前插入:

kconfig 复制代码
config RUST_GPIO_DEMO
    tristate "Rust GPIO demo driver"
    depends on RUST
    help
      A simple GPIO driver written in Rust for learning purposes.

drivers/gpio/Makefile 末尾追加:

makefile 复制代码
obj-$(CONFIG_RUST_GPIO_DEMO)    += rust_gpio_demo.o

编译

bash 复制代码
# 启用为模块
scripts/config --module CONFIG_RUST_GPIO_DEMO
make ARCH=riscv LLVM=1 olddefconfig

# 完整编译内核(不能单独 make xxx.ko)
env PATH="$HOME/.cargo/bin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
    make ARCH=riscv LLVM=1 -j$(nproc)

踩坑 2 :不能用 make drivers/gpio/rust_gpio_demo.ko 单独编译,modpost 在此模式下无法识别 Rust 模块的 MODULE_LICENSE,会报错。必须跑完整的 make
踩坑 3 :WSL 用户的 PATH 中含有 Windows 路径(如 /mnt/c/Program primecode.)包含空格,会导致 buildroot/内核 Makefile 报错。用 env PATH=... 传入干净的路径。

编译完成后确认产物:

bash 复制代码
ls -lh drivers/gpio/rust_gpio_demo.ko

在 QEMU 中测试

启动时通过 virtfs.ko 所在目录挂载进虚拟机:

bash 复制代码
qemu-system-riscv64 \
  -machine virt \
  -nographic \
  -kernel arch/riscv/boot/Image \
  -drive file=/path/to/rootfs.ext2,format=raw,if=none,id=hd0 \
  -device virtio-blk-device,drive=hd0 \
  -virtfs local,path=drivers/gpio,mount_tag=host0,security_model=mapped \
  -append "root=/dev/vda rw console=ttyS0" \
  -m 512M

在虚拟机内:

bash 复制代码
mkdir /mnt/host
mount -t 9p -o trans=virtio host0 /mnt/host

insmod /mnt/host/rust_gpio_demo.ko
dmesg | tail -3
# [  5.123456] rust_gpio_demo: Rust GPIO demo driver loaded!

rmmod rust_gpio_demo
dmesg | tail -3
# [  8.654321] rust_gpio_demo: Rust GPIO demo driver unloaded!

退出 QEMU:Ctrl+A 然后 X


坑位速查表

错误现象 根本原因 解决方案
HAVE_RUST=n,CONFIG_RUST 灰掉 RISC-V Rust 强依赖 Clang 改用 LLVM=1
unknown key "author" key 名称错误 改为 authors: ["..."]
missing MODULE_LICENSE() 单独编译绕过了 modpost 必须完整 make
PATH contains spaces WSL 注入 Windows 路径 env PATH=... 或关闭 appendWindowsPath
libclang not found bindgen 找不到 libclang sudo apt install libclang-dev

灯,亮了。


经验证,可以正常加载驱动。

本文总写作时间为2分钟,主要工作为copy-paste + 添加文章头。

验证时间为2小时左右,经过三次彻底重构,AI还整了个前后呼应,服。

bash 复制代码
buildroot login: root
# mkdir /mnt/host
# mount -t 9p -o trans=virtio host0 /mnt/host
# insmod /mnt/host/rust_gpio_demo.ko
[   40.826645] rust_gpio_demo: Rust GPIO demo driver loaded!
# dmesg | tail -3
[    1.945634]     TERM=linux
[    2.175759] EXT4-fs (vda): re-mounted acca20a9-4799-4758-b6d0-53df3dec1167.
[   40.826645] rust_gpio_demo: Rust GPIO demo driver loaded!
# rmmod rust_gpio_demo
[   57.943086] rust_gpio_demo: Rust GPIO demo driver unloaded!
# dmesg | tail -3
[    2.175759] EXT4-fs (vda): re-mounted acca20a9-4799-4758-b6d0-53df3dec1167.
[   40.826645] rust_gpio_demo: Rust GPIO demo driver loaded!
[   57.943086] rust_gpio_demo: Rust GPIO demo driver unloaded!
相关推荐
江公望2 小时前
Linux kernel devm_of_platform_populate()函数浅谈
linux
其实防守也摸鱼2 小时前
AWVS下载和安装保姆级教程
linux·服务器·git
洛洛呀。2 小时前
Kali系统桥接模式下相关网络故障
linux·服务器·桥接模式
李日灐2 小时前
<4>Linux 权限:从 Shell 核心原理 到 权限体系的底层逻辑 详解
linux·运维·服务器·开发语言·后端·面试·权限
寒秋花开曾相惜2 小时前
(学习笔记)4.1 Y86-64指令集体系结构(4.1.6 一些Y86-64指令 )
linux·运维·服务器·开发语言·笔记·学习·安全
freewlt2 小时前
TypeScript 5.5 新特性深度解析:类型系统的又一次进化
linux·ubuntu·typescript
сокол2 小时前
【网安-Web渗透测试-Linux提权】SUID提权
linux·前端·web安全·网络安全
誰能久伴不乏2 小时前
Qt 混合编程核心原理:C++ 与 QML 通信机制详解
linux·c++·qt·架构·状态模式
运维小斌2 小时前
麒麟v10arm使用dnsmasq部署本地DNS服务器
linux·运维·服务器·网络