Struct AddrSpace

Source
pub struct AddrSpace { /* private fields */ }
Expand description

The virtual memory address space.

Implementations§

Source§

impl AddrSpace

Source

pub const fn base(&self) -> VirtAddr

Returns the address space base.

Source

pub const fn end(&self) -> VirtAddr

Returns the address space end.

Source

pub fn size(&self) -> usize

Returns the address space size.

Source

pub const fn page_table(&self) -> &PageTable

Returns the reference to the inner page table.

Source

pub const fn page_table_root(&self) -> PhysAddr

Returns the root physical address of the inner page table.

Source

pub fn contains_range(&self, start: VirtAddr, size: usize) -> bool

Checks if the address space contains the given address range.

Source

pub fn new_empty(base: VirtAddr, size: usize) -> AxResult<Self>

Creates a new empty address space.

Source

pub fn copy_mappings_from(&mut self, other: &AddrSpace) -> AxResult

Copies page table mappings from another address space.

It copies the page table entries only rather than the memory regions, usually used to copy a portion of the kernel space mapping to the user space.

Note that on dropping, the copied PTEs will also be cleared, which could taint the original page table. For workaround, you can use AddrSpace::clear_mappings.

Returns an error if the two address spaces overlap.

Source

pub fn clear_mappings(&mut self, range: VirtAddrRange)

Clears the page table mappings in the given address range.

This should be used in pair with AddrSpace::copy_mappings_from.

Source

pub fn find_free_area( &self, hint: VirtAddr, size: usize, limit: VirtAddrRange, align: PageSize, ) -> Option<VirtAddr>

Searches for a contiguous free region in the virtual address space

This function searches for available virtual address space within a specified address range, based on the current memory region layout, that satisfies the size and alignment requirements.

§Parameters
  • hint: Suggested starting address for the search (may be adjusted due to alignment or overlapping regions)
  • size: Size of the contiguous address space to allocate (in bytes)
  • limit: Boundary of the allowed address range (inclusive of start and end addresses)
  • align: Address alignment requirement (e.g., page alignment like 4KB/2MB)
§Return Value
  • Some(VirtAddr): A starting virtual address that meets all requirements was found
  • None: No sufficient space was found within the specified range
§Implementation Logic
  1. Initialize last_end to the maximum aligned value between the hint and the start of the limit range
  2. First pass: handle regions before the hint to determine the initial search position
  3. Second pass: check gaps between regions:
    • Skip overlapping and already occupied regions
    • Check whether the gap between regions satisfies the size + alignment requirement
  4. Finally, verify that the found address is within the specified limit range
§Notes
  • Alignment is strictly enforced on candidate addresses (ensured via align_up)
  • The region must be fully contained within the limit range (end <= limit.end)
  • The search may ignore the hint if a better space is found in later regions
Source

pub fn map_linear( &mut self, start_vaddr: VirtAddr, start_paddr: PhysAddr, size: usize, flags: MappingFlags, align: PageSize, ) -> AxResult

Add a new linear mapping.

See Backend for more details about the mapping backends.

The flags parameter indicates the mapping permissions and attributes.

Returns an error if the address range is out of the address space or not aligned.

Source

pub fn map_alloc( &mut self, start: VirtAddr, size: usize, flags: MappingFlags, populate: bool, align: PageSize, ) -> AxResult

Add a new allocation mapping.

See Backend for more details about the mapping backends.

The flags parameter indicates the mapping permissions and attributes.

Returns an error if the address range is out of the address space or not aligned.

Source

pub fn populate_area( &mut self, start: VirtAddr, size: usize, _access_flags: MappingFlags, ) -> AxResult

Ensures that the specified virtual memory region is fully mapped.

This function walks through the given virtual address range and attempts to ensure that every page is mapped. If a page is not mapped and the corresponding area allows on-demand population (populate == false), it will trigger a page fault to map it. If access_flags contains WRITE, it will handle copy-on-write (COW) logic for already mapped pages that may require COW due to write intentions.

§Parameters
  • start: The starting virtual address of the region to map, which must be page-aligned.
  • size: The size (in bytes) of the region, which must also be page-aligned.
  • access_flags indicates the access type
§Returns

Returns Ok(()) if the entire region is successfully mapped, or an appropriate AxError variant (NoMemory, BadAddress) on failure.

§Errors
  • AxError::NoMemory: Failed to allocate.
  • AxError::BadAddress: An invalid mapping state was detected.
Source

pub fn unmap(&mut self, start: VirtAddr, size: usize) -> AxResult

Removes mappings within the specified virtual address range.

Returns an error if the address range is out of the address space or not aligned.

Source

pub fn unmap_user_areas(&mut self) -> AxResult

To remove user area mappings from address space.

Source

pub fn read(&self, start: VirtAddr, align: PageSize, buf: &mut [u8]) -> AxResult

To read data from the address space.

§Arguments
  • start - The start virtual address to read.
  • buf - The buffer to store the data.
Source

pub fn write(&self, start: VirtAddr, align: PageSize, buf: &[u8]) -> AxResult

To write data to the address space.

§Arguments
  • start_vaddr - The start virtual address to write.
  • buf - The buffer to write to the address space.
Source

pub fn protect( &mut self, start: VirtAddr, size: usize, flags: MappingFlags, ) -> AxResult

Updates mapping within the specified virtual address range.

Returns an error if the address range is out of the address space or not aligned.

Source

pub fn clear(&mut self)

Removes all mappings in the address space.

Source

pub fn check_region_access( &self, range: VirtAddrRange, access_flags: MappingFlags, ) -> bool

Checks whether an access to the specified memory region is valid.

Returns true if the memory region given by range is all mapped and has proper permission flags (i.e. containing access_flags).

Source

pub fn handle_page_fault( &mut self, vaddr: VirtAddr, access_flags: MappingFlags, ) -> bool

Handles a page fault at the given address.

access_flags indicates the access type that caused the page fault.

Returns true if the page fault is handled successfully (not a real fault).

Source

pub fn try_clone(&mut self) -> AxResult<Self>

Attempts to clone the current address space into a new one.

This method creates a new empty address space with the same base and size, then iterates over all memory areas in the original address space to copy or share their mappings into the new one.

§Behavior with cow Feature Enabled
  • For memory areas backed by Backend::Alloc, the populate flag is forced to false to avoid preemptive physical allocation in the new space.
  • All writable mappings have their WRITE flag removed, enforcing Copy-On-Write (COW) semantics.
  • Shared pages increase their reference count via frame_table().inc_ref(), and both the original and the cloned page tables are updated:
    • The original page’s protection flags are modified to remove write access.
    • The new address space maps the same physical page with the new flags.
§Behavior without cow Feature
  • Each mapped page in the original address space is copied into the corresponding address in the new address space.
  • If the target address in the new space is not mapped, a page fault will be handled, and memory is allocated before copying.
  • The actual copying is done using core::ptr::copy_nonoverlapping at the physical address level.

Trait Implementations§

Source§

impl Debug for AddrSpace

Source§

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

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

impl Drop for AddrSpace

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

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

Source§

fn into(self) -> U

Calls U::from(self).

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

Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

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

Source§

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

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

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

Performs the conversion.