pub struct AddrSpace { /* private fields */ }
Expand description
The virtual memory address space.
Implementations§
Source§impl AddrSpace
impl AddrSpace
Sourcepub const fn page_table(&self) -> &PageTable
pub const fn page_table(&self) -> &PageTable
Returns the reference to the inner page table.
Sourcepub const fn page_table_root(&self) -> PhysAddr
pub const fn page_table_root(&self) -> PhysAddr
Returns the root physical address of the inner page table.
Sourcepub fn contains_range(&self, start: VirtAddr, size: usize) -> bool
pub fn contains_range(&self, start: VirtAddr, size: usize) -> bool
Checks if the address space contains the given address range.
Sourcepub fn new_empty(base: VirtAddr, size: usize) -> AxResult<Self>
pub fn new_empty(base: VirtAddr, size: usize) -> AxResult<Self>
Creates a new empty address space.
Sourcepub fn copy_mappings_from(&mut self, other: &AddrSpace) -> AxResult
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.
Sourcepub fn clear_mappings(&mut self, range: VirtAddrRange)
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
.
Sourcepub fn find_free_area(
&self,
hint: VirtAddr,
size: usize,
limit: VirtAddrRange,
align: PageSize,
) -> Option<VirtAddr>
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 foundNone
: No sufficient space was found within the specified range
§Implementation Logic
- Initialize
last_end
to the maximum aligned value between the hint and the start of the limit range - First pass: handle regions before the hint to determine the initial search position
- Second pass: check gaps between regions:
- Skip overlapping and already occupied regions
- Check whether the gap between regions satisfies the
size + alignment
requirement
- 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
Sourcepub fn map_linear(
&mut self,
start_vaddr: VirtAddr,
start_paddr: PhysAddr,
size: usize,
flags: MappingFlags,
align: PageSize,
) -> AxResult
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.
Sourcepub fn map_alloc(
&mut self,
start: VirtAddr,
size: usize,
flags: MappingFlags,
populate: bool,
align: PageSize,
) -> AxResult
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.
Sourcepub fn populate_area(
&mut self,
start: VirtAddr,
size: usize,
_access_flags: MappingFlags,
) -> AxResult
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.
Sourcepub fn unmap(&mut self, start: VirtAddr, size: usize) -> AxResult
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.
Sourcepub fn unmap_user_areas(&mut self) -> AxResult
pub fn unmap_user_areas(&mut self) -> AxResult
To remove user area mappings from address space.
Sourcepub fn read(&self, start: VirtAddr, align: PageSize, buf: &mut [u8]) -> AxResult
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.
Sourcepub fn write(&self, start: VirtAddr, align: PageSize, buf: &[u8]) -> AxResult
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.
Sourcepub fn protect(
&mut self,
start: VirtAddr,
size: usize,
flags: MappingFlags,
) -> AxResult
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.
Sourcepub fn check_region_access(
&self,
range: VirtAddrRange,
access_flags: MappingFlags,
) -> bool
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
).
Sourcepub fn handle_page_fault(
&mut self,
vaddr: VirtAddr,
access_flags: MappingFlags,
) -> bool
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).
Sourcepub fn try_clone(&mut self) -> AxResult<Self>
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
, thepopulate
flag is forced tofalse
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.