1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
//! Rust has many useful abstractions and utils that require heap allocations.
//! `String`, `Vec` and `Box` are some of them. To be able to use them, we need
//! to allocate memory at runtime, which requires a custom allocator.
//!
//! If you want to find out more about it, please refer to the [alloc::GlobalAllocator](https://doc.rust-lang.org/std/alloc/trait.GlobalAlloc.html) and the [Rust book](https://doc.rust-lang.org/edition-guide/rust-2018/platform-and-target-support/global-allocators.html).
//!
//! ## Example
//!
//! Add the following to your code to define new global allocator:
//!
//! ```rust
//! use kernel_alloc::KernelAlloc;
//!
//! #[global_allocator]
//! static GLOBAL: KernelAlloc = KernelAlloc;
//! ```
#![no_std]
#![feature(alloc_error_handler)]
extern crate alloc;
use crate::nt::{ExAllocatePool, ExFreePool, PoolType};
use alloc::alloc::handle_alloc_error;
use core::alloc::{GlobalAlloc, Layout};
#[doc(hidden)] pub mod nt;
/// The global kernel allocator structure.
pub struct KernelAlloc;
unsafe impl GlobalAlloc for KernelAlloc {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let pool = ExAllocatePool(PoolType::NonPagedPool, layout.size());
if pool.is_null() {
handle_alloc_error(layout);
}
pool as _
}
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) { ExFreePool(ptr as _); }
}
#[alloc_error_handler]
fn alloc_error(layout: Layout) -> ! {
panic!("allocation failed: {:?}", layout);
}