13using namespace MaxOS::memory;
14using namespace MaxOS::common;
15using namespace MaxOS::processes;
36 for (
size_t i = 256; i < 512; i++) {
69 m_current_region = m_first_region;
70 m_first_region->next =
nullptr;
74 Logger::DEBUG() <<
"Next available address: 0x" << m_next_available_address <<
"\n";
87 while (
region !=
nullptr) {
90 for (
size_t i = 0; i < CHUNKS_PER_PAGE; i++) {
93 if (i == m_current_chunk &&
region == m_current_region)
98 for (
size_t j = 0; j <
pages; j++) {
143 if (address < m_next_available_address)
160 if (flags & VirtualFlags::RESERVE) {
164 for (
size_t i = 0; i <
pages; i++) {
181 if (m_current_chunk >= CHUNKS_PER_PAGE)
186 fill_up_to_address(address, flags,
false);
191 chunk->flags = flags;
192 chunk->start_address = m_next_available_address;
195 m_next_available_address += size;
200 return (
void*)
chunk->start_address;
204 for (
size_t i = 0; i <
pages; i++) {
208 ASSERT(
frame !=
nullptr,
"Failed to allocate frame (from current region)\n");
216 return (
void*)
chunk->start_address;
222void VirtualMemoryManager::new_region() {
233 new_region->next =
nullptr;
236 for (
size_t i = 0; i < CHUNKS_PER_PAGE; i++) {
237 new_region->chunks[i].size = 0;
238 new_region->chunks[i].flags = 0;
239 new_region->chunks[i].start_address = 0;
243 m_current_region->next = new_region;
245 m_current_region = new_region;
256 if (address ==
nullptr)
262 while (
region !=
nullptr) {
265 for (
size_t i = 0; i < CHUNKS_PER_PAGE; i++) {
275 if (
chunk !=
nullptr)
283 if (
chunk ==
nullptr)
287 if (
chunk->flags & VirtualFlags::SHARED) {
293 if(
resource.second->type() != resource_type_t::SHARED_MEMORY)
298 if((
void*)
shared->physical_address() != address)
307 add_free_chunk(
chunk->start_address,
chunk->size);
312 chunk->start_address = 0;
327 while (
region !=
nullptr) {
330 for (
size_t i = 0; i < CHUNKS_PER_PAGE; i++) {
333 if (
region->chunks[i].size != 0)
350void VirtualMemoryManager::add_free_chunk(
uintptr_t start_address,
size_t size) {
354 new_chunk->start_address = start_address;
370free_chunk_t* VirtualMemoryManager::find_and_remove_free_chunk(
size_t size) {
409 return m_pml4_root_physical_address;
424 if (
block !=
nullptr)
440 if (size == 0 || physical_address == 0)
462 for (
size_t i = 0; i <
pages; i++)
477void VirtualMemoryManager::fill_up_to_address(
uintptr_t address,
size_t flags,
bool mark_used) {
483 ASSERT(address >= m_next_available_address,
"FAILED TO FILL: Address is before the next available address - 0x%x < 0x%x\n", address, m_next_available_address);
486 size_t size = address - m_next_available_address;
491 chunk->flags = flags;
492 chunk->start_address = m_next_available_address;
495 m_next_available_address += size;
500 for (
size_t i = 0; i <
pages; i++) {
504 ASSERT(
frame !=
nullptr,
"Failed to allocate frame (from fill up)\n");
524 if (m_pml4_root_address ==
nullptr)
528 return m_pml4_root_address;
static Logger DEBUG()
Gets active logger set to DEBUG level.
Stores the left, top, width and height of a rectangle.
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...
static size_t align_to_page(size_t size)
Aligns a size to the page size.
static void clean_page_table(uint64_t *table)
Cleans a page table (fills it with 0 or null entries)
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...
static bool check_aligned(size_t size)
Checks if an address is aligned.
static PhysicalMemoryManager * s_current_manager
The current physical memory manager in use.
static size_t align_up_to_page(size_t size, size_t s_page_size)
Aligns a size up to the page size.
static size_t size_to_frames(size_t size)
Converts a size to the number of frames.
VirtualMemoryManager()
Construct a new Virtual Memory Manager object and set up the initial page tables (kernel mapped into ...
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 * allocate(size_t size, size_t flags)
Allocate a new chunk of virtual memory.
size_t memory_used()
Returns the amount of memory used.
uint64_t * pml4_root_address_physical()
Get the physical address of the PML4 root.
~VirtualMemoryManager()
Destroy the Virtual Memory Manager object and free all used pages.
uint64_t * pml4_root_address()
Get the virtual address of the PML4 root.
void free(void *address)
Free a chunk of virtual memory.
void * load_shared_memory(const string &name)
Load shared memory into the VMM's address space.
static Process * current_process()
Gets the process on the currently executing core.
A block memory that is mapped into multiple processes.
Defines a Logger class for logging messages with different severity levels to multiple output streams...
#define ASSERT(condition, format,...)
If the specified condition is not met then the kernel will crash with the specified message.
constexpr uint64_t HIGHER_HALF_DIRECT_MAP
Where the map of physical memory to higher half starts.
constexpr uint64_t PAGE_SIZE
The size of a page (4KB)
@ PRESENT
The page is present in memory.
@ WRITE
Memory in this page is writable.
Defines a GlobalScheduler and Scheduler for managing processes and threads.
A chunk of memory that has been freed and is available for allocation. A node in a linked list.
A container for a region of virtual memory that has been allocated by the Virtual Memory Manager.
Defines a VirtualMemoryManager class for managing virtual memory allocation and mapping to physical m...
struct PACKED MaxOS::memory::VirtualMemoryRegion virtual_memory_region_t
Alias for VirtualMemoryRegion struct.
@ SHARED
The memory is shared between multiple processes.
@ RESERVE
Reserve the memory but do not map any physical memory to it.