Skip to main content

Frames

Struct Frames 

Source
pub struct Frames<const RAM: bool, T = MaybeUninit<u8>> { /* private fields */ }
Available on crate feature full only.
Expand description

An owned region of physical memory.

If the region is allocated from conventional memory, then the RAM parameter is set, and the allocated memory can be directly accessed through get and get_mut via the page map region.

§Examples

use std::num::NonZero;
use kernel_api::allocator::highmem;
use kernel_api::memory::Frames;

// allocate some memory from `highmem`
let mut mem = highmem().allocate_one()?;

// initialise the memory with zeroes
let slice = mem.write_filled(0);

// once initialised, the memory can be accessed as a slice
slice[1] = 42;
info!("{}", slice[0]);

// the memory is deallocated when dropped
drop(mem);

Implementations§

Source§

impl<const RAM: bool, T> Frames<RAM, T>

Source

pub const fn pmm(&self) -> &DynPmm<'static, RAM>

Returns the physical memory allocator used for the underlying allocation.

§Examples
use kernel_api::allocator::highmem;

let mem = highmem().allocate_one()?;
let allocator = mem.pmm(); // this is a reference to the `highmem` allocator
Source

pub const fn count(&self) -> usize

Returns the number of allocated frames.

§Examples
use kernel_api::allocator::highmem;

let mem = highmem().allocate_one()?;
assert_eq!(mem.count(), 1);
Source

pub const fn base(&self) -> RawFrame

Returns the first frame of the allocation.

§Examples
use kernel_api::allocator::highmem;

let mem = highmem().allocate_one()?;
info!("allocation starts at {:?}", mem.base());
Source

pub fn as_frame_range(&self) -> Range<RawFrame> ⓘ

Returns the two RawFrames that span the allocation.

The returned range is half-open, which means that the end frame points one past the last frame of the allocation. This way, a zero sized allocation is represented by two equal frames, and the difference between the two frames represents the number of frames of the allocation.

§Examples
use kernel_api::allocator::highmem;
use core::ops::Range;

let mem = highmem().allocate_one()?;
let Range { start, end } = mem.as_frame_range();

info!("allocation starts at {start:?}");
assert_eq!(start + 1, end);
Source

pub const unsafe fn base_raw(self: *const Self) -> RawFrame

Equivalent to base() but taking a raw pointer for self.

§Safety

Behavior is undefined if any of the following conditions are violated:

  • self must be valid for reads.
  • self must be properly aligned.
  • self must point to a properly initialized value of Frames.
§Examples

See examples for base().

Source

pub const unsafe fn from_raw( raw: Range<RawFrame>, pmm: DynPmm<'static, RAM>, ) -> Self

Creates a Frames directly from its raw components.

§Safety

raw must be an unaliased region of memory allocated by the allocator pmm.

§Examples
use kernel_api::allocator::highmem;
use kernel_api::memory::Frames;

// manually allocate some memory
let allocator = highmem();
let start = allocator.allocate_one_raw()?;

// wrap it in `Frames` so it deallocates on drop
let frames = unsafe {
    Frames::from_raw(
        start..(start + 1),
        allocator,
    )
};
Source§

impl<const RAM: bool, T> Frames<RAM, MaybeUninit<T>>

Source

pub fn cast<U>(self) -> Frames<RAM, MaybeUninit<U>>

Casts the underlying type pointed to by the Frames.

This allows using a Frames object directly as a fixed size array for storing data with a lower alignment requirement than a page.

§Examples
use kernel_api::allocator::highmem;

let mem = highmem().allocate_one()?;
let mem = mem.cast::<u32>();
// `mem` can now be used as a `[u32]`
Source§

impl<T> Frames<true, MaybeUninit<T>>

Source

pub fn write_filled(&mut self, value: T) -> &mut [T]
where T: Clone,

Fills the memory region with elements by cloning value, returning a mutable reference to the now initialized contents of memory. Any previously initialized elements will not be dropped.

This is similar to [slice::fill].

§Panics

This function will panic if any call to Clone panics.

If such a panic occurs, any elements previously initialized during this operation will be dropped.

§Examples
use kernel_api::allocator::highmem;
use kernel_api::memory::PAGE_SIZE;

let mem = highmem().allocate_one()?;
let initialized = mem.write_filled(1);
assert_eq!(initialized, &[1; PAGE_SIZE]);
Source

pub fn write_filled_with(&mut self, f: impl FnMut(usize) -> T) -> &mut [T]

Fills the memory region with elements returned by calling a closure for each index, returning a mutable reference to the now initialized contents of memory. Any previously initialized elements will not be dropped.

This method uses a closure to create new values. If you’d rather Clone a given value, use write_filled. If you want to use the Default trait to generate values, you can pass [|_| Default::default()][Default::default] as the argument.

§Panics

This function will panic if any call to the provided closure panics.

If such a panic occurs, any elements previously initialized during this operation will be dropped.

§Examples
use kernel_api::allocator::highmem;
use kernel_api::memory::PAGE_SIZE;

let mem = highmem().allocate_one()?;
let initialized = mem.write_with(|idx| 1u8.wrapping_add(idx as u8));
assert_eq!(&initialized[..5], &[1, 2, 3, 4, 5]);
Source

pub fn into_filed(self, value: T) -> Frames<true, T>
where T: Clone,

Fills the memory region with elements by cloning value, consuming the Frames and returning a new object of the initialized type. Any previously initialized elements will not be dropped.

This is similar to [slice::fill].

§Panics

This function will panic if any call to Clone panics.

If such a panic occurs, any elements previously initialized during this operation will be dropped.

§Examples
use kernel_api::allocator::highmem;
use kernel_api::memory::PAGE_SIZE;

let mem = highmem().allocate_one()?;
let mem = mem.into_filed(1);
let initialized = mem.get();
assert_eq!(initialized, &[1; PAGE_SIZE]);
Source

pub fn into_filed_with(self, f: impl FnMut(usize) -> T) -> Frames<true, T>

Fills the memory region with elements returned by calling a closure for each index, consuming the Frames and returning a new object of the initialized type. Any previously initialized elements will not be dropped.

This method uses a closure to create new values. If you’d rather Clone a given value, use write_filled. If you want to use the Default trait to generate values, you can pass [|_| Default::default()][Default::default] as the argument.

§Panics

This function will panic if any call to the provided closure panics.

If such a panic occurs, any elements previously initialized during this operation will be dropped.

§Examples
use kernel_api::allocator::highmem;
use kernel_api::memory::PAGE_SIZE;

let mem = highmem().allocate_one()?;
let mem = mem.into_filed_with(|idx| 1u8.wrapping_add(idx as u8));
let initialized = mem.get();
assert_eq!(&initialized[..5], &[1, 2, 3, 4, 5]);
Source§

impl<T> Frames<true, T>

Source

pub const fn get(&self) -> &[T]

Returns a slice to the underlying memory.

This will fail to compile if T is a type with higher alignment requirements than a page guarantees.

§Examples
use core::mem::MaybeUninit;
use kernel_api::allocator::highmem;

let mem = highmem().allocate_one()?;
let buffer: &[MaybeUninit<u8>] = mem.get();
ⓘ
use kernel_api::allocator::highmem;

#[repr(align(8192))]
struct HighAlignment(u64);

let mem = highmem().allocate_one()?
let mem = mem.cast::<HighAlignment>();
mem.get();
Source

pub const fn get_mut(&mut self) -> &mut [T]

Returns a mutable slice to the underlying memory.

This will fail to compile if T is a type with higher alignment requirements than a page guarantees.

§Examples
use core::mem::MaybeUninit;
use kernel_api::allocator::highmem;

let mem = highmem().allocate_one()?;
let buffer: &mut [MaybeUninit<u8>] = mem.get_mut();
ⓘ
use kernel_api::allocator::highmem;

#[repr(align(8192))]
struct HighAlignment(u64);

let mem = highmem().allocate_one()?
let mut mem = mem.cast::<HighAlignment>();
mem.get_mut();

Trait Implementations§

Source§

impl<const RAM: bool, T> Debug for Frames<RAM, T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<const RAM: bool, T> Drop for Frames<RAM, T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

§

impl<const RAM: bool, T> Freeze for Frames<RAM, T>
where DynPmm<'static, RAM>: Freeze, PhantomData<[T]>: Freeze,

§

impl<const RAM: bool, T> RefUnwindSafe for Frames<RAM, T>
where DynPmm<'static, RAM>: RefUnwindSafe, PhantomData<[T]>: RefUnwindSafe,

§

impl<const RAM: bool, T> Send for Frames<RAM, T>
where DynPmm<'static, RAM>: Send, PhantomData<[T]>: Send,

§

impl<const RAM: bool, T> Sync for Frames<RAM, T>
where DynPmm<'static, RAM>: Sync, PhantomData<[T]>: Sync,

§

impl<const RAM: bool, T> Unpin for Frames<RAM, T>
where DynPmm<'static, RAM>: Unpin, PhantomData<[T]>: Unpin,

§

impl<const RAM: bool, T> UnsafeUnpin for Frames<RAM, T>
where DynPmm<'static, RAM>: UnsafeUnpin, PhantomData<[T]>: UnsafeUnpin,

§

impl<const RAM: bool, T> UnwindSafe for Frames<RAM, T>
where DynPmm<'static, RAM>: UnwindSafe, PhantomData<[T]>: UnwindSafe,

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = !

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.