Max OS 0.3
Loading...
Searching...
No Matches
MaxOS::memory::VirtualMemoryManager Class Reference

Manages the virtual memory of the system and provides functions to allocate and free memory in the virtual address space. More...

#include <virtual.h>

Public Member Functions

 VirtualMemoryManager ()
 Construct a new Virtual Memory Manager object and set up the initial page tables (kernel mapped into the hh)
 
 ~VirtualMemoryManager ()
 Destroy the Virtual Memory Manager object and free all used pages.
 
void * allocate (size_t size, size_t flags)
 Allocate a new chunk of virtual memory.
 
void * allocate (size_t requested_size, size_t &actual_size, size_t flags)
 Allocate a new chunk of virtual memory.
 
void * allocate (uint64_t address, size_t requested_size, size_t &actual_size, size_t flags)
 Allocate a new chunk of virtual memory at a specific address (ie for mmap io devices)
 
void free (void *address, bool reusable_pages=true)
 Free a chunk of virtual memory.
 
void * load_physical_into_address_space (uintptr_t physical_address, size_t size, size_t flags)
 Load physical memory into the VMM's address space.
 
void * load_range_from_process (VirtualMemoryManager *other_vmm, const void *start_address, size_t size)
 Loads the pages from a virtual memory region in another vmm into this one.
 
void unload_range_from_process (const void *start_address, size_t size)
 Unload a shared range of pages from this vmm.
 
void * load_shared_memory (const string &name)
 Load shared memory into the VMM's address space.
 
void * load_shared_memory (uintptr_t physical_address, size_t size)
 Load shared memory into the VMM's address space.
 
uint64_t * pml4_root_address ()
 Get the virtual address of the PML4 root.
 
uint64_t * pml4_root_address_physical ()
 Get the physical address of the PML4 root.
 
size_t memory_used ()
 Returns the amount of memory used.
 

Detailed Description

Manages the virtual memory of the system and provides functions to allocate and free memory in the virtual address space.

Note
Have to use a linked list as vector class depends on dynamic memory allocation (which depends on this)

Definition at line 104 of file virtual.h.

Constructor & Destructor Documentation

◆ VirtualMemoryManager()

VirtualMemoryManager::VirtualMemoryManager ( )

Construct a new Virtual Memory Manager object and set up the initial page tables (kernel mapped into the hh)

Note
Should only be called once per memory manager (kernel and each process)

Definition at line 25 of file virtual.cpp.

25 {
26
27 // Set the kernel flag
28 bool is_kernel = MemoryManager::s_kernel_memory_manager == nullptr;
29 if (!is_kernel) {
30
31 // Get a new pml4 table
32 m_pml4_root_physical_address = (uint64_t*)PhysicalMemoryManager::s_current_manager->allocate_frame();
33 m_pml4_root_address = (uint64_t*)PhysicalMemoryManager::to_dm_region((uint64_t)m_pml4_root_physical_address);
34
35 // Clear the table
36 PhysicalMemoryManager::clean_page_table(m_pml4_root_address);
37
38 // Map the higher half of the kernel (p4 256 - 511)
39 for (size_t i = 256; i < 512; i++) {
40
41 // Recursive Map the pml4 table (so that we can access the new pml4 table later on)
42 if (i == 510) {
43 m_pml4_root_address[i] = (uint64_t)m_pml4_root_physical_address | PRESENT | WRITE;
44 continue;
45 }
46
47 // Set the new pml4 table to the old (kernel) pml4 table
49
50 }
51
52 // Load the userspace pml4
53 asm volatile("mov %0, %%cr3"::"r"((uint64_t)m_pml4_root_physical_address) : "memory");
54
55 } else {
57 m_pml4_root_physical_address = (uint64_t*)PhysicalMemoryManager::to_lower_region((uint64_t)m_pml4_root_address);
58 }
59
60 // Set up the first region
61 new_region();
62 m_first_region = m_current_region;
63
64 // Calculate the next available address (kernel needs to reserve space for the higher half)
66}
static MemoryManager * s_kernel_memory_manager
The memory manager for any kernel processes and all kernel allocations.
static void * to_dm_region(uintptr_t physical_address)
Converts a physical address to a direct map region address if it is in the lower region using the hig...
Definition physical.cpp:929
uint64_t memory_size() const
Gets total the memory size available for use (allocated or not)
Definition physical.cpp:743
static void clean_page_table(uint64_t *table)
Cleans a page table (fills it with 0 or null entries)
Definition physical.cpp:636
uint64_t * pml4_root_address()
Gets the pml4 root address for the kernel.
Definition physical.cpp:733
static void * to_lower_region(uintptr_t virtual_address)
Converts a virtual address to a lower region address if it is in the higher region using the higher h...
Definition physical.cpp:898
static PhysicalMemoryManager * s_current_manager
The current physical memory manager in use.
Definition physical.h:183
constexpr uint64_t HIGHER_HALF_DIRECT_MAP
Where the map of physical memory to higher half starts.
Definition physical.h:99
constexpr uint64_t PAGE_SIZE
The size of a page (4KB)
Definition physical.h:92
constexpr size_t VMM_RESERVED
The starting address for the VMM to start allocating from when in higher half (otherwise can cause co...
Definition virtual.h:80

References MaxOS::memory::PhysicalMemoryManager::clean_page_table(), MaxOS::memory::HIGHER_HALF_DIRECT_MAP, MaxOS::memory::PhysicalMemoryManager::memory_size(), MaxOS::memory::PAGE_SIZE, MaxOS::memory::PhysicalMemoryManager::pml4_root_address(), MaxOS::memory::PRESENT, MaxOS::memory::PhysicalMemoryManager::s_current_manager, MaxOS::memory::MemoryManager::s_kernel_memory_manager, MaxOS::memory::PhysicalMemoryManager::to_dm_region(), MaxOS::memory::PhysicalMemoryManager::to_lower_region(), MaxOS::memory::VMM_RESERVED, and MaxOS::memory::WRITE.

◆ ~VirtualMemoryManager()

VirtualMemoryManager::~VirtualMemoryManager ( )

Destroy the Virtual Memory Manager object and free all used pages.

Definition at line 71 of file virtual.cpp.

71 {
72
73 // Free all the frames used by the VMM
74 virtual_memory_region_t* region = m_first_region;
75
76 // Loop through the regions
77 while (region != nullptr) {
78
79 // Loop through the chunks
80 for (size_t i = 0; i < CHUNKS_PER_PAGE; i++) {
81
82 // Have reached the end?
83 if (i == m_current_chunk && region == m_current_region)
84 break;
85
86 // Cant free shared frames that may be in use by another VMM
87 if (region->chunks[i].flags & SHARED)
88 continue;
89
90 // Free each page in the chunk
91 size_t pages = PhysicalMemoryManager::size_to_frames(region->chunks[i].size);
92 for (size_t j = 0; j < pages; j++) {
93
94 // Convert the virtual address to a physical address and free it
95 physical_address_t* frame = PhysicalMemoryManager::s_current_manager->get_physical_address((virtual_address_t*)(region->chunks[i].start_address + j * PAGE_SIZE), m_pml4_root_address);
96 if (frame != nullptr)
98
99 }
100 }
101
102 region = region->next;
103 }
104}
static size_t size_to_frames(size_t size)
Converts a size to the number of frames.
Definition physical.cpp:144
void free_frame(void *address)
Frees a frame in the bit map.
Definition physical.cpp:250
physical_address_t * get_physical_address(virtual_address_t *virtual_address, uint64_t *pml4_root)
Gets the physical address from a virtual address (if it exists)
Definition physical.cpp:828
void virtual_address_t
A type representing a virtual address (used for readability)
Definition physical.h:30
void physical_address_t
A type representing a physical address (used for readability)
Definition physical.h:31
struct PACKED MaxOS::memory::VirtualMemoryRegion virtual_memory_region_t
Alias for VirtualMemoryRegion struct.
constexpr size_t CHUNKS_PER_PAGE
Number of chunks per virtual memory region (limited to fit in one page)
Definition virtual.h:79

References MaxOS::memory::CHUNKS_PER_PAGE, MaxOS::memory::PhysicalMemoryManager::free_frame(), MaxOS::memory::PhysicalMemoryManager::get_physical_address(), MaxOS::memory::PAGE_SIZE, MaxOS::memory::PhysicalMemoryManager::s_current_manager, MaxOS::memory::SHARED, and MaxOS::memory::PhysicalMemoryManager::size_to_frames().

Member Function Documentation

◆ allocate() [1/3]

void * VirtualMemoryManager::allocate ( size_t  requested_size,
size_t &  actual_size,
size_t  flags 
)

Allocate a new chunk of virtual memory.

Parameters
requested_sizeThe size of the memory to allocate
actual_sizeThe size of the memory allocated (>= requested size)
flagsThe flags to set on the memory
Returns
The address of the allocated memory

Definition at line 127 of file virtual.cpp.

127 {
128
129 return allocate(0, requested_size, actual_size, flags);
130}
void * allocate(size_t size, size_t flags)
Allocate a new chunk of virtual memory.
Definition virtual.cpp:113

References allocate().

Referenced by allocate().

◆ allocate() [2/3]

void * VirtualMemoryManager::allocate ( size_t  requested_size,
size_t  flags 
)

Allocate a new chunk of virtual memory.

Parameters
requested_sizeThe size of the memory to allocate
flagsThe flags to set on the memory
Returns
The address of the allocated memory

Definition at line 113 of file virtual.cpp.

113 {
114
115 size_t actual_size;
116 return allocate(0, requested_size, actual_size, flags);
117}

References allocate().

Referenced by allocate(), MaxOS::memory::BumpMemoryManager::BumpMemoryManager(), load_physical_into_address_space(), load_range_from_process(), and MaxOS::processes::GlobalScheduler::prepare_initrd().

◆ allocate() [3/3]

void * VirtualMemoryManager::allocate ( uint64_t  address,
size_t  requested_size,
size_t &  actual_size,
size_t  flags 
)

Allocate a new chunk of virtual memory at a specific address (ie for mmap io devices)

Parameters
addressThe address to allocate at
requested_sizeThe size of the memory to allocate
actual_sizeThe size of the memory allocated (>= requested size)
flagsThe flags to set on the memory
Returns
The address of the allocated memory or nullptr if failed

Definition at line 142 of file virtual.cpp.

142 {
143
144 // Make sure allocating something
145 if (requested_size == 0)
146 return nullptr;
147
148 // If specific address is given
149 if (address != 0) {
150
151 // Make sure isn't already allocated
152 if (address < m_next_available_address)
153 return nullptr;
154
155 // Make sure its aligned
157 return nullptr;
158
159 }
160
161 // Make sure the size is aligned
162 actual_size = PhysicalMemoryManager::align_up_to_page(requested_size, PAGE_SIZE);
163
164 // Check the free list for a chunk (if not asking for a specific address)
165 free_chunk_t* reusable_chunk = address == 0 ? find_and_remove_free_chunk(actual_size) : nullptr;
166 if (reusable_chunk != nullptr) {
167
168 // If the chunk is being reserved then the old memory needs to be unmapped (as the owner of this reserved region will perform the mapping as required)
169 uintptr_t chunk_start = reusable_chunk->start_address;
170 if (flags & RESERVE) {
171
172 // Unmap the memory
173 size_t pages = PhysicalMemoryManager::size_to_frames(actual_size);
174 for (size_t i = 0; i < pages; i++) {
175
176 // Free the frame
177 physical_address_t* frame = PhysicalMemoryManager::s_current_manager->get_physical_address((virtual_address_t*)(chunk_start + i * PAGE_SIZE), m_pml4_root_address);
178 if (frame != nullptr)
180
181 // Unmap the page
182 auto page = (virtual_address_t*)(chunk_start + (i * PAGE_SIZE));
183 if (page != nullptr)
184 PhysicalMemoryManager::s_current_manager->unmap(page, m_pml4_root_address);
185
186 }
187 }
188
189 // Ensure there is enough space if no reusable chunk is found
190 if (m_current_chunk >= CHUNKS_PER_PAGE)
191 new_region();
192
193 // Allocate the memory
194 virtual_memory_chunk_t* chunk = &m_current_region->chunks[m_current_chunk++];
195 chunk->size = actual_size;
196 chunk->flags = flags;
197 chunk->start_address = chunk_start;
198
199 // Return the address
200 return (void*)chunk_start;
201 }
202
203 // Is there space in the current region
204 if (m_current_chunk >= CHUNKS_PER_PAGE)
205 new_region();
206
207 // If needed to allocate at a specific address, fill with free memory up to that address to prevent fragmentation
208 if (address != 0)
209 fill_up_to_address(address, flags, false);
210
211 // fill_up_to_address() may have filled the last slot.
212 if (m_current_chunk >= CHUNKS_PER_PAGE)
213 new_region();
214
215 // Allocate the memory
216 virtual_memory_chunk_t* chunk = &m_current_region->chunks[m_current_chunk];
217 chunk->size = actual_size;
218 chunk->flags = flags;
219 chunk->start_address = m_next_available_address;
220
221 // Update the next available address
222 m_next_available_address += actual_size;
223 m_current_chunk++;
224
225 // If just reserving the space don't map it
226 if (flags & RESERVE)
227 return (void*)chunk->start_address;
228
229 // Map the memory
230 size_t pages = PhysicalMemoryManager::size_to_frames(actual_size);
231 for (size_t i = 0; i < pages; i++) {
232
233 // Allocate a new frame
235 ASSERT(frame != nullptr, "Failed to allocate frame (from current region)\n");
236
237 // Map the frame
238 PhysicalMemoryManager::s_current_manager->map(frame, (virtual_address_t*)(chunk->start_address + i * PAGE_SIZE), PRESENT | WRITE, m_pml4_root_address);
239
240 }
241
242 // Return the address
243 return (void*)chunk->start_address;
244}
void unmap(virtual_address_t *virtual_address)
Unmaps a virtual address using the kernel's pml4 table.
Definition physical.cpp:590
virtual_address_t * map(virtual_address_t *virtual_address, size_t flags)
Allocates a physical address to a virtual address.
Definition physical.cpp:535
static bool check_aligned(size_t size)
Checks if an address is aligned.
Definition physical.cpp:178
static size_t align_up_to_page(size_t size, size_t s_page_size)
Aligns a size up to the page size, given a page size to a power of 2.
Definition physical.cpp:167
void * allocate_frame()
Allocates a physical page of memory, if the PMM is not initalise it will use the anon memory instead ...
Definition physical.cpp:188
A chunk of memory that has been freed and is available for allocation. A node in a linked list.
Definition virtual.h:71
uintptr_t start_address
The first virtual address that this chunk covers.
Definition virtual.h:73
A container for a region of virtual memory that has been allocated by the Virtual Memory Manager.
Definition virtual.h:54
size_t flags
The flags for the memory (see VirtualFlags)
Definition virtual.h:58
uintptr_t start_address
The first virtual address that this chunk covers.
Definition virtual.h:56
size_t size
The size of the chunk's memory region in bytes.
Definition virtual.h:57

References MaxOS::memory::PhysicalMemoryManager::align_up_to_page(), MaxOS::memory::PhysicalMemoryManager::allocate_frame(), MaxOS::memory::PhysicalMemoryManager::check_aligned(), MaxOS::memory::CHUNKS_PER_PAGE, MaxOS::memory::VirtualMemoryChunk::flags, MaxOS::memory::PhysicalMemoryManager::free_frame(), MaxOS::memory::PhysicalMemoryManager::get_physical_address(), MaxOS::memory::PhysicalMemoryManager::map(), MaxOS::memory::PAGE_SIZE, MaxOS::memory::PRESENT, MaxOS::memory::RESERVE, MaxOS::memory::PhysicalMemoryManager::s_current_manager, MaxOS::memory::VirtualMemoryChunk::size, MaxOS::memory::PhysicalMemoryManager::size_to_frames(), MaxOS::memory::VirtualMemoryChunk::start_address, MaxOS::memory::FreeChunk::start_address, MaxOS::memory::PhysicalMemoryManager::unmap(), and MaxOS::memory::WRITE.

◆ free()

void VirtualMemoryManager::free ( void *  address,
bool  reusable_pages = true 
)

Free a chunk of virtual memory.

Parameters
addressThe address of the memory to free
reusable_pagesCan these pages be reused (chunk will be added to free list)

Definition at line 282 of file virtual.cpp.

282 {
283
284 // Make sure freeing something
285 if (address == nullptr)
286 return;
287
288 // Find the chunk
289 virtual_memory_region_t* region = m_first_region;
290 virtual_memory_chunk_t* chunk = nullptr;
291 while (region != nullptr) {
292
293 // Loop through the chunks
294 for (size_t i = 0; i < CHUNKS_PER_PAGE; i++) {
295
296 // Check if the address is in the chunk
297 if (region->chunks[i].start_address == (uintptr_t)address) {
298 chunk = &region->chunks[i];
299 break;
300 }
301 }
302
303 // If the chunk was found
304 if (chunk != nullptr)
305 break;
306
307 // Move to the next region
308 region = region->next;
309 }
310
311 // Make sure the chunk was found
312 if (chunk == nullptr)
313 return;
314
315 // No longer using a shared memory chunk
316 if (chunk->flags & VirtualFlags::SHARED) {
317
318 // Find the resource
319 for (const auto& resource : GlobalScheduler::current_process()->resource_manager.resources()) {
320 if (resource.second->type() != resource_type_t::SHARED_MEMORY)
321 continue;
322
323 // Skip shared memory that points elsewhere TODO: this is vaddr so get paddr and comapre?
324 auto shared = (SharedMemory*)resource.second;
325 if ((void*)shared->physical_address() != address)
326 continue;
327
328 // Close the resource
330 }
331 }
332
333 // Can only re use pages we own
334 if (reusable_pages && !(chunk->flags & (SHARED | RESERVE)))
335 add_free_chunk(chunk->start_address, chunk->size);
336
337 // Clear the chunk
338 chunk->size = 0;
339 chunk->flags = 0;
340 chunk->start_address = 0;
341}
The global scheduler that manages all processes and threads across all cores.
Definition scheduler.h:28
static Process * current_process()
Gets the process on the currently executing core.
resources::ResourceManager resource_manager
The manger for resources used by this process.
Definition process.h:122
A block memory that is mapped into multiple processes.
Definition ipc.h:45
void close_resource(uint64_t handle, size_t flags)
Un registers the resource and then closes it.
Definition resource.cpp:262

References MaxOS::memory::CHUNKS_PER_PAGE, MaxOS::processes::resources::ResourceManager::close_resource(), MaxOS::processes::GlobalScheduler::current_process(), MaxOS::memory::VirtualMemoryChunk::flags, MaxOS::memory::RESERVE, MaxOS::processes::Process::resource_manager, MaxOS::processes::resources::ResourceManager::resources(), MaxOS::memory::SHARED, MaxOS::memory::VirtualMemoryChunk::size, and MaxOS::memory::VirtualMemoryChunk::start_address.

Referenced by unload_range_from_process().

◆ load_physical_into_address_space()

void * VirtualMemoryManager::load_physical_into_address_space ( uintptr_t  physical_address,
size_t  size,
size_t  flags 
)

Load physical memory into the VMM's address space.

Parameters
physical_addressThe physical address of the memory
sizeThe size of the memory
flagsThe flags to set on the memory
Returns
The address of the memory in the VMM's address space

Definition at line 524 of file virtual.cpp.

524 {
525
526 // Reserve some space
527 void* address = allocate(size, flags | RESERVE);
528
529 // Map the shared memory
530 size_t pages = PhysicalMemoryManager::size_to_frames(size);
531 for (size_t i = 0; i < pages; i++)
532 PhysicalMemoryManager::s_current_manager->map((physical_address_t*)(physical_address + (i * PAGE_SIZE)), (virtual_address_t*)((uintptr_t)address + (i * PAGE_SIZE)), PRESENT | WRITE, m_pml4_root_address);
533
534
535 // All done
536 return address;
537}

References allocate(), MaxOS::memory::PAGE_SIZE, MaxOS::memory::PRESENT, MaxOS::memory::RESERVE, MaxOS::memory::PhysicalMemoryManager::s_current_manager, MaxOS::memory::PhysicalMemoryManager::size_to_frames(), and MaxOS::memory::WRITE.

Referenced by load_shared_memory().

◆ load_range_from_process()

void * VirtualMemoryManager::load_range_from_process ( VirtualMemoryManager *  other_vmm,
const void *  start_address,
size_t  size 
)

Loads the pages from a virtual memory region in another vmm into this one.

Parameters
other_vmmThe vmm that contains the region
start_addressThe starting virtual address of the region
sizeThe length in bytes of the region
Returns
The virtual address for the region in this vmm
Warning
Re security see todo: https://discord.com/channels/578193015433330698/884443149919993856/1471057118407950436
Todo:

maybe move from void* to uint8* ??

take flags for mapping (ro)

Definition at line 552 of file virtual.cpp.

552 {
553
554 // Check bounds
555 if (!other_vmm || !start_address || size == 0)
556 return nullptr;
557
558 // Convert given region to be page orientated
559 size_t aligned_start = PhysicalMemoryManager::align_direct_to_page((size_t)start_address);
560 size_t offset = (size_t)start_address - aligned_start;
561 size_t total_size = offset + size;
562 size_t paged_size = PhysicalMemoryManager::align_up_to_page(total_size, PAGE_SIZE);
563
564 // Reserve space to receive the copy
565 auto dest = allocate(paged_size, RESERVE);
566 if (!dest)
567 return nullptr;
568
569 // Find the pages that contains the chunk
570 size_t range_pages = paged_size / PAGE_SIZE;
571
572 // Map each page in the range
573 for (size_t i = 0; i < range_pages; i++) {
574 uintptr_t virtual_page = aligned_start + i * PAGE_SIZE;
575
576 // Haven't reached the start of the region
577 if (virtual_page + PAGE_SIZE <= aligned_start)
578 continue;
579
580 // Dont copy pages past the region
581 if (virtual_page >= aligned_start + paged_size)
582 break;
583
584 // Map the page into this vmm
586 if (frame == nullptr)
587 continue;
588
589 PhysicalMemoryManager::s_current_manager->map(frame, (virtual_address_t*)(dest + virtual_page - aligned_start), PRESENT | WRITE, m_pml4_root_address);
590 }
591
592 // Return where the region actually starts, not the chunk
593 return dest + offset;
594}
static size_t align_direct_to_page(size_t size)
Aligns a address to the page size.
Definition physical.cpp:764
uint64_t * pml4_root_address()
Get the virtual address of the PML4 root.
Definition virtual.cpp:691

References MaxOS::memory::PhysicalMemoryManager::align_direct_to_page(), MaxOS::memory::PhysicalMemoryManager::align_up_to_page(), allocate(), MaxOS::memory::PhysicalMemoryManager::get_physical_address(), MaxOS::memory::PhysicalMemoryManager::map(), MaxOS::memory::PAGE_SIZE, pml4_root_address(), MaxOS::memory::PRESENT, MaxOS::memory::RESERVE, MaxOS::memory::PhysicalMemoryManager::s_current_manager, and MaxOS::memory::WRITE.

◆ load_shared_memory() [1/2]

void * VirtualMemoryManager::load_shared_memory ( const string &  name)

Load shared memory into the VMM's address space.

Parameters
nameThe name of the shared memory
Returns
The address of the shared memory in the VMM's address space

Definition at line 487 of file virtual.cpp.

487 {
488
489 // Get the shared memory block
491
492 // Load the shared memory
493 if (block != nullptr)
494 return load_shared_memory(block->physical_address(), block->size());
495
496 return nullptr;
497}
void * load_shared_memory(const string &name)
Load shared memory into the VMM's address space.
Definition virtual.cpp:487
Resource * get_resource(uint64_t handle)
Gets a resource based on the handle id.
Definition resource.cpp:282

References MaxOS::processes::GlobalScheduler::current_process(), MaxOS::processes::resources::ResourceManager::get_resource(), load_shared_memory(), and MaxOS::processes::Process::resource_manager.

Referenced by MaxOS::processes::resources::BridgeHandler::BridgeHandler(), load_shared_memory(), and MaxOS::processes::SharedMemory::open().

◆ load_shared_memory() [2/2]

void * VirtualMemoryManager::load_shared_memory ( uintptr_t  physical_address,
size_t  size 
)

Load shared memory into the VMM's address space.

Parameters
physical_addressThe physical address of the shared memory
sizeThe size of the shared memory
Returns
The address of the shared memory in the VMM's address space

Definition at line 506 of file virtual.cpp.

506 {
507
508 // Make sure there is somthing to map
509 if (size == 0 || physical_address == 0)
510 return nullptr;
511
512 // Load it into physical memory
513 return load_physical_into_address_space(physical_address, size, SHARED);
514}
void * load_physical_into_address_space(uintptr_t physical_address, size_t size, size_t flags)
Load physical memory into the VMM's address space.
Definition virtual.cpp:524

References load_physical_into_address_space(), and MaxOS::memory::SHARED.

◆ memory_used()

size_t VirtualMemoryManager::memory_used ( )

Returns the amount of memory used.

Returns
The amount of memory used

Definition at line 348 of file virtual.cpp.

348 {
349
350 // Loop through all the regions and add up the size of the allocated chunks
351 size_t result = 0;
352
353 // Iterate through the regions
354 virtual_memory_region_t* region = m_first_region;
355 while (region != nullptr) {
356
357 // Loop through the chunks
358 for (size_t i = 0; i < CHUNKS_PER_PAGE; i++) {
359
360 // Check if the address is in the chunk
361 if (region->chunks[i].size != 0)
362 result += region->chunks[i].size;
363 }
364
365 // Move to the next region
366 region = region->next;
367 }
368
369 return result;
370}

References MaxOS::memory::CHUNKS_PER_PAGE.

◆ pml4_root_address()

uint64_t * VirtualMemoryManager::pml4_root_address ( )

Get the virtual address of the PML4 root.

Returns
The virtual address or nullptr if not found

Definition at line 691 of file virtual.cpp.

691 {
692
693 // Make sure the address is valid
694 if (m_pml4_root_address == nullptr)
695 return nullptr;
696
697 // Return the address
698 return m_pml4_root_address;
699}

Referenced by load_range_from_process().

◆ pml4_root_address_physical()

uint64_t * VirtualMemoryManager::pml4_root_address_physical ( )

Get the physical address of the PML4 root.

Returns
The physical address of the PML4 root

Definition at line 476 of file virtual.cpp.

476 {
477
478 return m_pml4_root_physical_address;
479}

Referenced by MaxOS::memory::BumpMemoryManager::switch_active_memory_manager().

◆ unload_range_from_process()

void VirtualMemoryManager::unload_range_from_process ( const void *  start_address,
size_t  size 
)

Unload a shared range of pages from this vmm.

Parameters
start_addressThe start of the range
sizeThe length of the range in bytes

Definition at line 602 of file virtual.cpp.

602 {
603
604 // Check bounds
605 if (!start_address || size == 0)
606 return;
607
608 // Convert given region to be page orientated
609 size_t aligned_start = PhysicalMemoryManager::align_direct_to_page((size_t)start_address);
610 size_t offset = (size_t)start_address - aligned_start;
611 size_t total_size = offset + size;
612 size_t paged_size = PhysicalMemoryManager::align_up_to_page(total_size, PAGE_SIZE);
613
614 // Find the chunk that contains the region
615 auto containing_chunk = find_containing_chunk(start_address, size);
616 size_t chunk_pages = PhysicalMemoryManager::size_to_frames(containing_chunk->size);
617
618 // Unmap each page in the range
619 for (size_t i = 0; i < chunk_pages; i++) {
620 uintptr_t virtual_page = containing_chunk->start_address + i * PAGE_SIZE;
621
622 // Haven't reached the start of the region
623 if (virtual_page + PAGE_SIZE <= aligned_start)
624 continue;
625
626 // Dont unmap pages past the region
627 if (virtual_page >= aligned_start + paged_size)
628 break;
629
630 // Free the page
631 PhysicalMemoryManager::s_current_manager->unmap((virtual_address_t*)virtual_page, m_pml4_root_address);
632 }
633
634 // Free the whole region
635 free((void*)aligned_start, false);
636}
void free(void *address, bool reusable_pages=true)
Free a chunk of virtual memory.
Definition virtual.cpp:282

References MaxOS::memory::PhysicalMemoryManager::align_direct_to_page(), MaxOS::memory::PhysicalMemoryManager::align_up_to_page(), free(), MaxOS::memory::PAGE_SIZE, MaxOS::memory::PhysicalMemoryManager::s_current_manager, MaxOS::memory::PhysicalMemoryManager::size_to_frames(), and MaxOS::memory::PhysicalMemoryManager::unmap().

Referenced by MaxOS::processes::resources::BridgeHandler::send_to_bridge().


The documentation for this class was generated from the following files: