To know how to configure Rust in the Linux Kernel, check out this post and to know how to test it check out this other post.

Add an empty module

In the kernel folder, open the Kconfig file which contains the configuration options organized in a tree structure within the menuconfig and custimizable through it.

$ cd linux
$ vim samples/rust/Kconfig

Copy another option and add it with the propoer modifications such as:

menuconfig SAMPLES_RUST_TEST_MODULE
    tristate "Test module"
    help
        This option builds the Rust test program samples.

        To compile this as a module, choose M here:
        the module will be called rust_test.

        If unsure, say N.

Then, open the makefile

$ vim samples/rust/Makefile

and edit it addign the new option:

obj-$(SAMPLES_RUST_TEST_MODULE)    += rust_test_module.o

Create an empty file for the module where we’ll add the code in the next step:

$ touch sampel/rust/rust_test_module.rs

You can check that your module has been added by running the rust-analyzer and check into the rust-project.json file

$ make rust-analyzer
$ cat rust-project.json | grep rust_test_module
    "display_name": "rust_test_module",
    "root_module": "linux/samples/rust/rust_test_module.rs"

Write the Rust source file

Open the samples/rust/rust_test_module.rs file and insert your Rust code:

// Test module
use kernel::prelude::*;

module! {
    type: TestMod,
    name: b"test",
    license: b"GPL",
}

struct TestMod;

impl kernel::Module for TestMod {
    fn init(_name: &'static CStr, _module: &'static ThisModule) -> Result<Self> {
        pr_info!("------------------------\n");
        pr_info!("hello world test module!\n");
        pr_info!("------------------------\n");
        Ok(TestMod)
    }
}

The module! macro creates the module, while the init() function prints a message during the initialization in order to see it during the OS start.

Build the kernel with the new module

To build the kernel with the new module, we need to select the new module option and compile the kernel.

So, open menuconfig to configure the kernel source

make menuconfig

and enable the Rust test module that is located at:

Main menu ->
    Kernel hacking ->
        Sample kernel code ->
            Rust samples ->
                Rust test module [*]

Save the configurations file and overwrite the old .config file.

Finally, build the kernel:

make -j8

Start the kernel

Once the kernel is ready, you can start a qemu instance of the kernel

qemu-system-x86_64 -nographic -kernel vmlinux -initrd initrd.img -nic user,model=rtl8139,hostfwd=tcp::5555-:23

and, if everything works well, you should see during the boot on the terminal

[] test_module: -----------------------
[] test_module: hello world test module!
[] test_module: -----------------------

Reload the module

If you want to modifiy the Rust source code and reload the module you can use the cargo-watch tool that watches over the source file and runs the cargo commands, such as:

cargo init .
cargo install cargo-watch
cargo watch -w ./samples/rust/rust_test_module.rs -cs 'make && qemu-system-x86_64 -m 3G -smp 2 -kernel bzImage -append "root=/dev/sda console=ttyS0 earlyprintk=serial net.ifnames=0" -drive file=bullseye.img,format=raw -net user,host=10.0.2.10,hostfwd=tcp::10021-:22 -net nic,model=e1000 -enable-kvm -nographic'

With similar result, you can add the rust-watch configuration in the Makefile to add the command and execute it from terminal:

PHONY += rustwatch
rustwatch:
    $(Q) cargo watch -w ./samples/rust/rust_test_module.rs -cs 'make && qemu-system-x86_64 -m 3G -smp 2 -kernel bzImage -append "root=/dev/sda console=ttyS0 earlyprintk=serial net.ifnames=0" -drive file=bullseye.img,format=raw -net user,host=10.0.2.10,hostfwd=tcp::10021-:22 -net nic,model=e1000 -enable-kvm -nographic'

PHONY += rustvm
rustvm:
    $(Q) make && qemu-system-x86_64 -m 3G -smp 2 -kernel bzImage -append "root=/dev/sda console=ttyS0 earlyprintk=serial net.ifnames=0" -drive file=bullseye.img,format=raw -net user,host=10.0.2.10,hostfwd=tcp::10021-:22 -net nic,model=e1000 -enable-kvm -nographic

and, then, use the commands:

# Build and start the VM
make rustvm
# Start a rust-watch that rebuilds and start the VM when file changes
make rustwatch