Posted on :: Tags: ,

A lot has changed since I wrote my first blog post on how to write kernel drivers with Rust. I learned more about the language and worked on more projects. The goal of this blog post is to keep you updated on the changes from the last 2 years.

Kernel Logging

When I originally wrote Kernel Printing with Rust, I had never heard or used the log crate. It's very powerful and you should definitely use it instead of some custom macros.

By using the log crate, we can easily switch between a kernel logger or serial port logger. Here's an implementation using my kernel-log crate:

#![no_std]

use kernel_log::KernelLogger;

#[no_mangle]
pub extern "system" fn DriverEntry() -> u64 {
    KernelLogger::init(LevelFilter::Info).expect("Failed to initialize logger");

    log::warn!("This is an example message.");

    0 /* STATUS_SUCCESS */
}

Crates

Over the time, I realized that creating a new kernel driver is quite a lot of effort. That's why I decided to extract the generic parts and turn them into crates.

Ecosystem

There are still no official bindings. :( But there's an open GitHub Issue for that. Feel free to add a comment and upvote it.

I also found the ntapi crate, which has a kernel feature. They don't have all kernel functions, but it's a good start. I defined the headers myself most of the time. You can also automatically generate them using bindgen.

Closing words

It's great to see that so many people started to choose Rust for kernel drivers. I'll try to keep this document updated with the latest changes.

Here's some great work by others, which might help you get started:

Feel free to message me if I forgot to add something. Thanks for reading!