[Rust Driver] Let's try build example rust linux driver.
Table of Contents
In October, Rust for linux is under the linux-next, not stable
Thus this article would be out-of-date before Linux 6.1 stable comes.
modules, out-of-tree #
There are two main ways to develop kernel modules. In-Of-Tree and Out-Of-Tree. In this article, we’re going to make the Out-Of-Tree method a Rust kernel module.
Before we start #
Check your kernel has been compiled with CONFIG_RUST=y
.
#
Check with following command.
zcat /proc/config.gz | grep -i CONFIG_RUST=y
The result comes with CONFIG_RUST=y
.
But you may not check from /proc/config.gz
when using distibution kernel image that downloaded or pre-installed.
Prepare $KDIR
#
$KDIR
is path of kernel source.
In this article path of kernel source that system used for boot with CONFIG_RUST
.
In my case it’s ~/Develop/linux
# /home/pmnxis/Develop/linux
export KDIR=$HOME/Develop/linux
Looking in to code #
Let’s preview the code rust_out_of_tree.rs
…
License and imports #
|
|
Lines 1~3, show file’s license information.
If you are write the code in company, SomeCompanyName
instead GPL-2.0
or just keep GPL-2.0
.
|
|
Line 5 means, bring rust for linux library for this code.
In following example module written in C were include like this.
|
|
|
|
Line 8, implement of the module trait.
Line 9, name of the module, if we written c, it’s the name of *.ko name field.
Line 10~12, those fields are simillar with below the example written in c. Those fields are same purpose.
|
|
We preview macro_rule! module
shortly. You can see detail here.
module!
See details ⇀Actual implements #
|
|
I just guess working as …
- On init (
insmod
?), print out somewhere with textRust out-of-tree sample (init)
vec<i32>[72, 108, 200]
is stored some kernel memory space with structRustOutOfTree
.- When drop the module (
rmmod
?), will print out with text[72, 108, 200]
.
By the way, we need to keep on eyes here.
|
|
In line 24, try_push
is not exsting in std::Vec
. In rust kernel programming, need to use try_push
instead std::Vec::push
.
alloc::vec::Vec
See details ⇀Also there's some `init` and `drop` functions in line 20 and 33. The code covers those function with `impl for` pattern.
I will explain about implementation and it’s philosophy later article.
Run code #
Build it #
make LLVM=1
My rust acceptable kernel build were buiten with LLVM.
So I compile the kernel module with LLVM.
Install module #
sudo insmod ./rust_out_of_tree.ko
After compile, we can there’s rust_out_of_tree.ko
inside of project directory.
We can install module with insmod
that normally used before.
Inspect result #
# do `sudo rmmod rust_out_of_tree` if you already install the module`
# clear all of dmesg log
sudo dmesg -C
# install the module
sudo insmod ./rust_out_of_tree.ko
# see log
dmesg
# uninstall the module
sudo rmmod rust_out_of_tree
# check log again.
dmesg
We can check the inspect actual result with above commands.
As we guess it prints with [72, 108, 200]
.
Conclusion #
We can summary from this simple kernel module.
Summary #
- Need to use
use kernel::prelude::*;
on top of code. module!
macro to define some description and board my own struct to the kernel module.kernel::Module
templete functions …. -WIP-- In kernel programming, use
alloc::vec::Vec
insteadstd::Vec
. pr_info
is just same as way to write withC
.
Reference #
- https://github.com/Rust-for-Linux/rust-out-of-tree-module
- https://www.kernel.org/doc/html/latest/kbuild/modules.html
- https://github.com/Rust-for-Linux/linux
- https://rust-for-linux.github.io/docs/kernel/prelude/index.html
- https://rust-for-linux.github.io/docs/kernel/prelude/macro.module.html
- https://rust-for-linux.github.io/docs/kernel/prelude/struct.Vec.html