ESC
输入关键词搜索文章标题和内容

Rust Linux内核驱动从零实战

本文由 linuxROS 整理发布,首发于 linuxros.cn,转载请注明出处。

Rust Linux内核驱动从零实战

导读

本文带你从零搭建最简Linux内核驱动,涵盖环境搭建、代码编写到编译加载全流程。所有命令可直接复制运行,零基础也能快速上手,掌握Rust驱动开发核心技能。

为什么选择Rust写驱动

Rust在内核开发中具备以下核心优势:

  • 内存安全:编译期检查杜绝空指针、野指针、缓冲区溢出
  • 零成本抽象:性能与C语言相当,无运行时开销
  • 现代化工具链:Cargo包管理,依赖管理便捷
  • 并发安全:所有权系统天然避免数据竞争

2026年Linux内核正式将Rust纳入主线支持,底层开发迎来新趋势。

驱动开发环境搭建

1. Linux环境前置准备

在Ubuntu/Debian系统执行以下命令,安装内核开发依赖:

sudo apt update
sudo apt install -y build-essential linux-headers-$(uname -r) llvm clang lld libelf-dev

2. 安装Rust工具链

系统默认未预装Rust,需先完成安装。

推荐方式(官方脚本):

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

安装过程中按 1 选择默认安装,完成后刷新环境变量:

source "$HOME/.cargo/env"

国内镜像源方式(网络受限时使用):

export RUSTUP_DIST_SERVER=https://rsproxy.cn
export RUSTUP_UPDATE_ROOT=https://rsproxy.cn/rustup
curl -sSf https://rsproxy.cn/rustup-init.sh | sh
source "$HOME/.cargo/env"

验证安装成功:

rustc --version
cargo --version

3. 安装Rust编译目标

rustup target add x86_64-unknown-none
rustup component add rust-src

创建最精简的Rust驱动

1. 创建驱动项目

cd ~
mkdir rust_linux_driver
cd rust_linux_driver

2. 编写Rust核心代码

创建 Cargo.toml:

[package]
name = "rust_linux_driver"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["staticlib"]

[dependencies]

[profile.release]
panic = "abort"
opt-level = "s"

创建 src/lib.rs:

#![no_std]

use core::ffi::c_int;

const HELLO_MSG: &[u8] = b"[rust_driver] Hello Rust Linux Kernel Driver!\n\0";
const BYE_MSG: &[u8] = b"[rust_driver] Goodbye Rust Linux Driver!\n\0";

#[no_mangle]
pub extern "C" fn rust_init_module() -> c_int {
    unsafe {
        printk(HELLO_MSG.as_ptr() as *const u8);
    }
    0
}

#[no_mangle]
pub extern "C" fn rust_cleanup_module() {
    unsafe {
        printk(BYE_MSG.as_ptr() as *const u8);
    }
}

extern "C" {
    fn printk(fmt: *const u8, ...) -> c_int;
}

#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
    loop {}
}

3. 创建C语言包装层

由于当前内核未启用CONFIG_RUST,需要通过C包装层调用Rust代码。

创建 wrapper.c:

来自 linuxros.cn · linuxROS
#include <linux/module.h>
#include <linux/kernel.h>

extern int rust_init_module(void);
extern void rust_cleanup_module(void);

int init_module(void)
{
    pr_info("C wrapper: calling Rust init\n");
    return rust_init_module();
}

void cleanup_module(void)
{
    pr_info("C wrapper: calling Rust cleanup\n");
    rust_cleanup_module();
}

MODULE_LICENSE("GPL");
MODULE_AUTHOR("linuxros");
MODULE_DESCRIPTION("Rust Linux Kernel Driver with C wrapper");

4. 创建Makefile编译脚本

obj-m += rust_linux_driver.o
rust_linux_driver-objs := wrapper.o rust_driver.o

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
RUST_LIB := target/x86_64-unknown-none/release/librust_linux_driver.a

all:
    cargo build --release --target x86_64-unknown-none
    ar x $(RUST_LIB) librust_linux_driver-0.1.0.o
    mv librust_linux_driver-0.1.0.o rust_driver.o
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) clean
    rm -f rust_driver.o *.o
    cargo clean

关键技术点:

  • #![no_std]:禁用标准库,内核环境不支持std
  • staticlib:编译为静态库,从中提取.o文件供内核链接
  • #[no_mangle]:防止函数名被编译器混淆
  • wrapper.c:C语言包装层,调用Rust导出的函数
  • ar x:从静态库中提取目标文件

编译、加载与测试

1. 编译Rust库并生成内核模块

make

编译流程:
1. Cargo编译Rust代码为静态库
2. 使用ar从静态库中提取.o目标文件
3. 内核构建系统将C代码和Rust目标文件链接生成.ko文件

编译成功后生成 rust_linux_driver.ko 内核模块。

2. 加载驱动

sudo insmod rust_linux_driver.ko

3. 查看内核日志

dmesg | tail -n 5

应能看到:

[rust_driver] Hello Rust Linux Kernel Driver!

4. 卸载驱动

sudo rmmod rust_linux_driver
dmesg | tail -n 5

应能看到:

[rust_driver] Hello Rust Linux Kernel Driver!
[rust_driver] Goodbye Rust Linux Driver!

常见问题解决

编译报错can't find crate for core:需安装x86_64-unknown-none目标,执行rustup target add x86_64-unknown-none。

编译报错extern blocks must be unsafe:Rust 2024版本要求extern块必须标记为unsafe。使用Rust 2021版本可避免此问题。

MODPOST错误 No such file or directory:内核构建系统无法直接处理.a文件。需使用ar x从静态库中提取.o文件后再链接。

内核未启用CONFIG_RUST:Ubuntu默认内核未启用Rust支持。可通过grep CONFIG_RUST /boot/config-$(uname -r)检查。本方案使用C包装层解决此限制。

insmod权限不足:必须使用sudo执行,内核模块加载需要root权限。

dmesg无输出:日志可能被内核过滤,尝试sudo dmesg -w实时监控,或检查dmesg -n 8调整日志级别。

安装rustup失败:如无法访问官方服务器,使用国内镜像源方式安装。

总结

本文完整覆盖Rust Linux驱动开发全流程,通过C包装层巧妙绕过内核CONFIG_RUST限制。所有代码可直接复制运行,适合快速入门。后续可深入学习内核原生Rust API、设备驱动框架、中断处理等高级特性。

搞笑图片

版权声明

作者linuxROS
协议本作品采用 CC BY-NC-SA 4.0 许可协议:署名-非商业性使用-相同方式共享
关注欢迎关注微信公众号 linuxROS,获取更多机器人 / 嵌入式 / Linux 干货
返回首页