服务粉丝

我们一直在努力
当前位置:首页 > 财经 >

如何使用 rust 写内核模块

日期: 来源:阿里巴巴中间件收集编辑:卜比


近年来,Rust 语言以内存安全、高可靠性、零抽象等能力获得大量开发者关注,而这些特性恰好是内核编程中所需要的,所以我们看下如何用rust来写Linux内核模块。


01

Rust 与内核模块

Aliware

虽然 Rust 支持已经在 LinuxKernel6.1 版本合并到主线了,所以理论上来说,开发者可以使用 Rust 来为 Linux6.1 写内核模块。


但实际开发工作中,内核版本不是最新的,比如 Debian 11 的内核就是 5.10 版本的,那么在这种情况下,该如何用 Rust 写内核模块呢?


02

原理

Aliware

  1. Rust 如何向内核注册回调、如何调用内核代码。Rust 和 C 的互操作性
  2. Rust 如何编译到目标平台上。Rust 的 target 配置
  3. Rust 如何申明内核模块入口、并添加特殊 section。Rust 内核模块的二进制约定

01


Rust 和 C 的互操作性

第一个问题基本上就是 C 和 Rust 的互操作性了。

得益于 Rust 的抽象层次,C 语言和 Rust 的互相调用都是比较容易的。rust 官方也提供了 bindgen 这样,根据 .h 文件生成 .rs 文件的库。

这样一来,貌似直接使用 bindgen 将内核头文件翻译成 .rs 就可以了?

但还有一个问题,如何获取内核头文件路径呢?

可以使用一个 dummy 内核模块,在编译过程中把编译参数导出来,其中包含了头文件路径,编译参数等,用于 bindgen 生成代码。

02


Rust 和 target 配置

内核模块和普通的程序相比,主要的不同在于:

  1. 内核模块是 freestanding 的,没有 libc、内存分配也比较原始
  2. 内核模块对于异常处理等有特殊约定

Rust 提供了 no_std 机制,可以让 rust 代码编译成 freestanding 二进制;Rust 也提供了自定义 target 的方式,可以自定义声明生成二进制的规范。

03


内核模块的二进制约定

内核对内核模块有一些约定:

  • 通过 .modinfo 等 section 来声明模块信息
  • 提供 init_module、cleanup_module 来提供内核模块的安装和卸载功能

在这一块,Rust 提供了 link_section 来自定义 section,也支持 extern "C"来导出函数。

此外,这些底层的操作,可以由内核提供一些 C 语言宏来简化代码,Rust 也提供了宏,可以用来做类似的事情。

02

一个小例子

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!


已在内核 5.10.0-17-amd64 上测试。

具体的代码以及相关配置,可以参考 GitHub 仓库:
https://github.com/robberphex/linux-kernel-module-rust


03

一些小细节

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"    ],}

  • 其他高级功能

比如字符设备、sysctl 等功能,可以参考项目中相关的测试代码。

04

更多规划

Aliware

  • 和 Rust-for-Linux 保持 API 一致。(Rust-for-Linux 例子:https://github.com/Rust-for-Linux/linux/blob/d9b2e84c0700782f26c9558a3eaacbe1f78c01e8/samples/rust/rust_chrdev.rs
  • Rust 提供的内存安全性、零抽象等能力,恰好是内核领域亟需的特性和能力。比如内核态如果出现内存泄漏、野指针,一会造成很大影响、二来也很难调试。在这个领域,我们可以借助Rust的能力来构造更加安全、更大的项目。

原始项目是 fishinabarrel/linux-kernel-module-rust,但目前提示使用 rust-for-linux,已经 archived。然而,考虑到目前旧版本内核还有很多,所以我重新修复了这个项目的一些环境,让大家在旧版本内核上能够用 Rust 编写内核模块。

相关阅读

  • 2.14~来上海数慧官网感受我们的“新”意满满!

  • 2.14 全面上新上海数慧官网一年一度的情人节又来啦!今天#情人节礼物#这个话题也在一大早就直接冲上热搜,各种花式礼物让小编羡慕不已。实不相瞒,数小慧也为大家准备了一份惊喜,
  • 基金从业押题上新!短期提分神器,抓紧用!!

  • 距离2月基金从业考试,仅剩5天!!!现在大家最着急的事情就是:如何快速提分?如何一次就能拿证?(押题购买见文末)我们常说:不看书、不刷题,裸考都能考30+,但是能不能考60分还得看备考和冲刺

热门文章

  • “复活”半年后 京东拍拍二手杀入公益事业

  • 京东拍拍二手“复活”半年后,杀入公益事业,试图让企业捐的赠品、家庭闲置品变成实实在在的“爱心”。 把“闲置品”变爱心 6月12日,“益心一益·守护梦想每一步”2018年四

最新文章

  • 如何使用 rust 写内核模块

  • 近年来,Rust 语言以内存安全、高可靠性、零抽象等能力获得大量开发者关注,而这些特性恰好是内核编程中所需要的,所以我们看下如何用rust来写Linux内核模块。01Rust 与内核模块A
  • 闲话 dubbogo 社区

  • dubbogo 社区发展 7 年多,dubbogo 登记用户已达 63 家【详见 https://github.com/apache/dubbo-go/issues/2 】,真实用户应该更多。于某在支持某 dubbogo 用户时,曾提议让他们
  • 极氪汽车 APP 系统云原生架构转型实践

  • 前言Aliware新能源汽车已经成为我国汽车市场再次崛起的关键支柱,随着新能源汽车市场的快速发展,不同类型的品牌造车厂商呈现出百花齐放的态势。极氪汽车是吉利控股集团旗下高