如何使用 rust 写内核模块

news2025/1/10 3:52:53

4d49b178ca354afe55fc25f895a81614.gif

近年来,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为底层,提供了println
use 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!

7cd7baa7e1da722690b4953b98bebe4a.png

已在内核 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 编写内核模块。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/71276.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

酷开科技不断革新,引领营销新动向

不管渠道如何变迁&#xff0c;不管场景如何碎片化、多样化&#xff0c;只要家庭文明不解体&#xff0c;只要我们的审美不发生颠覆性变迁&#xff0c;家庭大屏就会是主要营销战场。 随着行业软硬件技术的更迭&#xff0c;智能化OTT终将打通互联网消费场景&#xff0c;带动智能电…

Linux 文件与目录

我们知道Linux的目录结构为树状结构&#xff0c;最顶级的目录为根目录 /。 其他目录通过挂载可以将它们添加到树中&#xff0c;通过解除挂载可以移除它们。 在开始本教程前我们需要先知道什么是绝对路径与相对路径。 绝对路径&#xff1a; 路径的写法&#xff0c;由根目录 /…

186:vue+openlayers 小汽车移动轨迹动画,带开始、暂停、结束控制键

第186个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+openlayers中实现轨迹动画,这里设置了小汽车开始,暂停,结束等的控制键,采用了线段步长位置获取坐标来定位点的方式来显示小车的动态。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果; 注意…

全国计算机等级考试-Python

计算机二级python 一、 题型及分值分布1. 单选题共40道&#xff0c;1到10题为公共基础知识&#xff0c;11到40题是python相关的知识&#xff0c;比如数据结构与算法、python基础知识。 每道题1分&#xff0c;共40分&#xff1b;2. 基础编程题共3道&#xff0c;题目会…

DocArray 和 Redis 联手,让推荐系统飞起来

在DocArray中使用Redis后端&#xff0c;基于向量相似性搜索可以快速搭建一个实时商品推荐系统。现在&#xff0c;跟上我们的脚步&#xff0c;一起了解搭建系统的关键步骤&#xff0c;并且深入了解推荐的原理吧&#xff01;推荐系统会根据用户画像、历史行为&#xff08;如购买、…

人工智能和数据分析成为 2023 年最大的计划投资

©网络研究院 到 2023 年&#xff0c;新兴技术系统将继续投资和发展&#xff0c;人工智能将引领私营公司计划利用的技术。 IT 分析公司 Info-Tech Research Group 对 2023 年的新行业预测进行了详细说明&#xff0c;预计私营部门公司将继续在其日常业务运营中采用更先进…

科普篇|法治宣传线上答题活动小程序界面功能全介绍

科普篇|法治宣传线上答题活动小程序界面功能全介绍 为深入学习贯彻二十大精神&#xff0c;努力使尊法学法守法用法在全社会蔚然成风&#xff0c;切实推动全民法治宣传教育深入开展&#xff0c;xx举办全民法治宣传线上答题活动。 第一、主界面展示 ①标题、主题、单位名称落款…

数据结构与算法之《二叉树》详解

标题&#xff1a;二叉树的思路及代码实现 作者&#xff1a;Ggggggtm 寄语&#xff1a;与其忙着诉苦&#xff0c;不如低头赶路&#xff0c;奋路前行&#xff0c;终将遇到一番好风景 文章目录 一、树的概念及结构 二、二叉树的概念及结构 2、1 二叉树的概念 2、2 二叉树的特点 2、…

机器学习之单变量线性回归

1、线性回归基础概念&#xff1a; 回归模型&#xff1a;regression model数据集&#xff1a;包含feature&#xff08;输入变量&#xff09;和与之对应的target&#xff08;输出变量&#xff09;训练集&#xff1a;training set输入数据&#xff1a;x&#xff08;feature or in…

玩转redis(二)——redis持久化

文章目录前言一、RDB1.save 和 bgsave对比2.RDB的优点和缺点2.1 优点2.2 缺点二、AOF1.AOF重写2.AOF的优点和缺点2.1 优点2.2 缺点3 RDB和AOF对比三、AOFRDB混合持久化1 原理2 如图Redis数据备份策略&#xff08;其实就是去备份我们的rdb/aof两个文件&#xff09;&#xff1a;四…

LeetCode刷题复盘笔记—一文搞懂完全背包之139. 单词拆分问题(动态规划系列第十六篇)

今日主要总结一下动态规划完全背包的一道题目&#xff0c;139. 单词拆分 题目&#xff1a;139. 单词拆分 Leetcode题目地址 题目描述&#xff1a; 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。 注意&#xff1a;…

(附源码)SSM失物招领平台 毕业设计 271621

SSM失物招领平台的设计与实现 摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对失物招领等问…

红队隧道应用篇之MsfPortfwd端口转发(三)

简介 Meterpreter shell中的portfwd命令最常用作透视技术&#xff0c;允许直接访问攻击系统无法访问的机器, 例如不出网的内网主机, 前提是你要有一个此内网网段的能出网的主机的Meterpreter shell 命令参数 add: 增加端口转发 delete: 删除指定的端口转发 list: 查看端口转…

Spring Cloud Alibaba Nacos 安装

1.Nacos 官网下载地址 Releases alibaba/nacos GitHub 2.使用 rz 命令上传到 虚拟机上 3.解压 tar -zxvf nacos-server-2.1.2.tar.gz 注&#xff1a;解压后&#xff0c;可以直接启动&#xff0c;访问地址&#xff1a;http://192.168.10.121:8848/nacos/ 用户名:nacos 密码:n…

JavaEE进阶:Bean 作⽤域和⽣命周期

文章目录一、Bean 的作用域问题1、案例2、分析二、作用域定义1、Bean 的 6 种作用域① singleton② prototype③ request④ session⑤ application⑥ websocket⑦ 单例作用域(singleton)和全局作用域(application)区别2、设置作用域3、案例修改三、Bean 原理分析1、Bean 执行流…

学生花卉网网页设计作品 学生鲜花网页模板 简单在线花店主页成品 鲜花网页制作 HTML学生花店商城网站作业设计

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

vue3 创建项目、安装依赖、启动项目

1. 搭建vue开发环境 下载安装最新版node.js https://blog.csdn.net/weixin_41192489/article/details/117979077 2. 执行项目创建命令 打开命令行工具 cnpm init vuelatest无 cnpm 的朋友先执行 npm i cnpm 遇到这种提示时&#xff0c;输入 y 回车 3. 选择项目创建配置 参考下…

安卓玩机搞机技巧综合资源-----关闭miui广告 怎么省电 替换开机动画 LOGO 锁屏 壁纸等等【五】

接上篇 安卓玩机搞机技巧综合资源------如何提取手机分区 小米机型代码分享等等 【一】 安卓玩机搞机技巧综合资源------开机英文提示解决dm-verity corruption your device is corrupt. 设备内部报错 AB分区等等【二】 安卓玩机搞机技巧综合资源------EROFS分区格式 小米红…

Windows OpenGL ES 图像白平衡色温

目录 一.OpenGL ES 图像白平衡色温 1.原始图片2.效果演示 二.OpenGL ES 图像白平衡色温源码下载三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 特效 零…

Sentinel规则持久化

Sentinel规则持久化 根据之前遇到的问题可以看出&#xff0c;当服务关闭后Sentinel就不会再有对应的信息&#xff0c;也就是临时保存的&#xff0c;下面就是要进行持久化的保存 将限流配置规则持久化进Nacos保存&#xff0c;只要刷新8401某个rest地址&#xff0c;sentinel控制台…