9 releases

0.2.5 Sep 5, 2024
0.2.4 Sep 2, 2024
0.2.3 Aug 30, 2023
0.2.2 Jul 4, 2023
0.1.0 Aug 21, 2020

#114 in Memory management

Download history 660/week @ 2024-08-19 321/week @ 2024-08-26 965/week @ 2024-09-02 449/week @ 2024-09-09 464/week @ 2024-09-16 52/week @ 2024-09-23 86/week @ 2024-09-30 913/week @ 2024-10-07 731/week @ 2024-10-14 224/week @ 2024-10-21 93/week @ 2024-10-28 535/week @ 2024-11-04 14/week @ 2024-11-11 406/week @ 2024-11-18 227/week @ 2024-11-25 248/week @ 2024-12-02

899 downloads per month

Custom license

12KB
142 lines

Rust crates.io docs.rs

kernel-alloc-rs

A custom memory allocator tailored for the Windows kernel space.

Why?

Rust has many useful abstractions and utils that require heap allocations, such as String, Vec, and Box. To be able to use them in the Windows kernel space, we need to allocate memory at runtime, which requires a custom allocator. This crate provides such allocators tailored for the Windows kernel.

For more information on custom allocators in Rust, refer to the alloc::GlobalAllocator and alloc::Allocator documentation. Additionally, the Rust book provides details on global_allocator and allocator_api.

Example

To use KernelAlloc or PhysicalAllocator as your global allocator, add the appropriate code to your kernel module:

For KernelAlloc:

use kernel_alloc::KernelAlloc;

#[global_allocator]
static GLOBAL: KernelAlloc = KernelAlloc;

For PhysicalAllocator:

use kernel_alloc::PhysicalAllocator;

#[global_allocator]
static GLOBAL: PhysicalAllocator = PhysicalAllocator;

Using with Box

Once you've set up KernelAlloc or PhysicalAllocator as your global allocator, you can use Box and other heap-allocated types just like you would in a standard Rust environment.

Here's an example demonstrating how to use both KernelAlloc and PhysicalAllocator with Box to allocate memory for different structs in the Windows kernel:

use kernel_alloc::{KernelAlloc, PhysicalAllocator};
use core::mem;

pub const PAGE_SIZE: usize = 0x1000;
pub const KERNEL_STACK_SIZE: usize = 0x6000;
pub const STACK_CONTENTS_SIZE: usize = KERNEL_STACK_SIZE - (mem::size_of::<*mut u64>() * 2);

#[repr(C, align(4096))]
pub struct Vmxon {
    pub revision_id: u32,
    pub data: [u8; PAGE_SIZE - 4],
}

#[repr(C, align(4096))]
pub struct HostStackLayout {
    pub stack_contents: [u8; STACK_CONTENTS_SIZE],
    pub padding_1: u64,
    pub reserved_1: u64,
}

pub struct Vmx {
    pub vmxon_region: Box<Vmxon, PhysicalAllocator>,
    pub host_rsp: Box<HostStackLayout, KernelAlloc>,
}

impl Vmx {
    pub fn new() -> Result<Self, AllocError> {
        let vmxon_region = unsafe { Box::try_new_zeroed_in(PhysicalAllocator)?.assume_init() };
        let host_rsp = unsafe { Box::try_new_zeroed_in(KernelAlloc)?.assume_init() };

        Ok(Self {
            vmxon_region: vmxon_region,
            host_rsp: host_rsp,
        })
    }
}

Credits / References

Dependencies

~225KB