Every's Blog

My First Code Patch in the Linux Kernel

· Christian

Overview

This patch is about the process to convert a stream of bytes into specific data types.

Modeling the problem

Let’s think of a stream of bytes as a block, so if I have one byte (aka 8 bits) I’ll use one block and in this block I’ve the data I wanna transform, in this case imagine it as the number 2 (0b10).

Visual representation of a stream of bytes as a block

Shaping the block

So far we’ve worked with the abstract form of the data which’s a block with the content inside, but what I want is to shape and manipulate this data. In high level languages like Rust, we’ve types that accept bit patterns, so if I have one block I can call it as u8 data type.

Getting the hands dirty

Now we understood the problem, so we’re capable of starting translating it into Rust. Remember that I called it a block? Now we represent the blocks as a Slice of Bytes (u8).

 1use core::mem::size_of;
 2
 3unsafe impl FromBytes for u8 {
 4    fn from_bytes(bytes: &[u8]) -> Option<&Self> {
 5        let slice_ptr = bytes.as_ptr().cast::<Self>();
 6        if bytes.len() == core::mem::size_of::<Self>() {
 7            unsafe { Some(&*slice_ptr) }
 8        } else {
 9            None
10        }
11    } /// Mutable implementation below

Wow, great job! It’s finished, right? Not yet!!

Alignment

Rust doesn’t have the unsafe keyword for nothing. When you convert the slice to a type. it’s possible that the data isn’t aligned with its original form for any reason, such something going wrong during the cast. So we need to check!

 1use core::mem::size_of;
 2
 3unsafe impl FromBytes for u8 {
 4    fn from_bytes(bytes: &[u8]) -> Option<&Self> {
 5        let slice_ptr = bytes.as_ptr().cast::<Self>();
 6        if bytes.len() == core::mem::size_of::<Self>() && slice_ptr.is_aligned() {
 7            unsafe { Some(&*slice_ptr) }
 8        } else {
 9            None
10        }
11    } /// Mutable implementation below

If for some reason, you wanna do it manually just change the if to:

1  if bytes.len() == size_of::Self<()> && (ptr as usize) % align_of::<Self>() {}

The end and acknowledgements

For the last part of the patch, I wrote the documentation that was probably the hardest part to me and it’s very important, so if you plan to contribute to Rust for Linux know that it’s a big point for your patchs. I have to thanks a lot people from Nvidia and Alexandre Corbout in special that give me a lot of support in the patch approval process.

Thanks for lkcamp too, I began my journey there.

A huge thanks for my girlfriend that show lkcamp to me and give me inconditional support.

If you wanna see the code working click here

Link for the patch Discussion

#kernel dev #linux #rust