日期:
来源:阿里巴巴中间件收集编辑:卜比
近年来,Rust 语言以内存安全、高可靠性、零抽象等能力获得大量开发者关注,而这些特性恰好是内核编程中所需要的,所以我们看下如何用rust来写Linux内核模块。
Rust 与内核模块
Aliware
虽然 Rust 支持已经在 LinuxKernel6.1 版本合并到主线了,所以理论上来说,开发者可以使用 Rust 来为 Linux6.1 写内核模块。
但实际开发工作中,内核版本不是最新的,比如 Debian 11 的内核就是 5.10 版本的,那么在这种情况下,该如何用 Rust 写内核模块呢?
原理
Aliware
Rust 如何向内核注册回调、如何调用内核代码。Rust 和 C 的互操作性 Rust 如何编译到目标平台上。Rust 的 target 配置 Rust 如何申明内核模块入口、并添加特殊 section。Rust 内核模块的二进制约定
Rust 和 C 的互操作性
Rust 和 target 配置
内核模块是 freestanding 的,没有 libc、内存分配也比较原始 内核模块对于异常处理等有特殊约定
内核模块的二进制约定
通过 .modinfo 等 section 来声明模块信息 提供 init_module、cleanup_module 来提供内核模块的安装和卸载功能
一个小例子
Aliware
#![no_std]// no_std用于表示没有std库,即freestanding环境extern crate alloc;use alloc::borrow::ToOwned;use alloc::string::String;// 我们以printk为底层,提供了printlnuse linux_kernel_module::println;// 这个struct代表内核模块struct HelloWorldModule {message: String,}// 实现内核模块初始化方法impl linux_kernel_module::KernelModule for HelloWorldModule {fn init() -> linux_kernel_module::KernelResult<Self> {println!("Hello kernel module from rust!");Ok(HelloWorldModule {message: "on the heap!".to_owned(),})}}// 提供内核模块卸载方法impl Drop for HelloWorldModule {fn drop(&mut self) {println!("My message is {}", self.message);println!("Goodbye kernel module from rust!");}}// 通过kernel_module宏,export了内核模块的相关信息linux_kernel_module::kernel_module!(HelloWorldModule,author: b"Fish in a Barrel Contributors",description: b"An extremely simple kernel module",license: b"GPL");
$ cd linux-kernel-module-rust/hello-world$ RUST_TARGET_PATH=$(pwd)/.. cargo +nightly xbuild --target x86_64-linux-kernel-module$ make$ insmod helloworld.ko$ rmmod helloworld$ dmesg | tail -n 3[521088.916091] Hello kernel module from rust![521174.204889] My message is on the heap![521174.204891] Goodbye kernel module from rust!
一些小细节
Aliware
VSCode 支持
由于 rust-analyzer 对于自定义 target,多模块的支持不够,所以我们暂时需要手动配置下 settings.json 才能正常开发:
{"rust-analyzer.cargo.extraEnv": {"RUST_TARGET_PATH": "/root/linux-kernel-module-rust"},"rust-analyzer.cargo.target": "x86_64-linux-kernel-module","rust-analyzer.server.extraEnv": {"RA_LOG": "lsp_server=debug","RUST_TARGET_PATH": "/root/linux-kernel-module-rust"},"rust-analyzer.trace.server": "verbose","rust-analyzer.linkedProjects": ["hello-world/Cargo.toml","Cargo.toml"],}
其他高级功能
更多规划
Aliware
和 Rust-for-Linux 保持 API 一致。(Rust-for-Linux 例子:https://github.com/Rust-for-Linux/linux/blob/d9b2e84c0700782f26c9558a3eaacbe1f78c01e8/samples/rust/rust_chrdev.rs) Rust 提供的内存安全性、零抽象等能力,恰好是内核领域亟需的特性和能力。比如内核态如果出现内存泄漏、野指针,一会造成很大影响、二来也很难调试。在这个领域,我们可以借助Rust的能力来构造更加安全、更大的项目。