-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Page Allocation & Mapping Virtutal Memory Space per process (& kernel) Kernel and Physical memory moved to higher half
- Loading branch information
1 parent
495b2e6
commit 83c72e6
Showing
24 changed files
with
1,926 additions
and
230 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
- Are to dos completed? | ||
- Are all the files in the correct location? | ||
- Kprintf used where necessary - no testing information? | ||
- Tested to ensure that the changes work? | ||
- Doxygen comments added? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
// | ||
// Created by 98max on 1/30/2024. | ||
// | ||
|
||
#ifndef MAXOS_MEMORY_PHYSICAL_H | ||
#define MAXOS_MEMORY_PHYSICAL_H | ||
|
||
#include <stdint.h> | ||
#include <stddef.h> | ||
#include <system/multiboot.h> | ||
|
||
namespace MaxOS { | ||
|
||
namespace memory { | ||
|
||
|
||
#define PMLX_GET_INDEX(ADDR, LEVEL) (((uint64_t)ADDR & ((uint64_t)0x1ff << (12 + LEVEL * 9))) >> (12 + LEVEL * 9)) | ||
|
||
#define PML4_GET_INDEX(ADDR) PMLX_GET_INDEX(ADDR, 3) | ||
#define PML3_GET_INDEX(ADDR) PMLX_GET_INDEX(ADDR, 2) | ||
#define PML2_GET_INDEX(ADDR) PMLX_GET_INDEX(ADDR, 1) | ||
#define PML1_GET_INDEX(ADDR) PMLX_GET_INDEX(ADDR, 0) | ||
|
||
// Useful for readability | ||
typedef void virtual_address_t; | ||
typedef void physical_address_t; | ||
|
||
typedef enum PageFlags { | ||
None = 0, | ||
Present = (1 << 0), | ||
Write = (1 << 1), | ||
User = (1 << 2), | ||
WriteThrough = (1 << 3), | ||
CacheDisabled = (1 << 4), | ||
Accessed = (1 << 5), | ||
Dirty = (1 << 6), | ||
HugePage = (1 << 7), | ||
Global = (1 << 8) | ||
|
||
} page_flags_t; | ||
|
||
|
||
// Struct for a page table entry | ||
typedef struct PageTableEntry { | ||
uint64_t present : 1; | ||
uint64_t write : 1; | ||
uint64_t user : 1; | ||
uint64_t write_through : 1; | ||
uint64_t cache_disabled : 1; | ||
uint64_t accessed : 1; | ||
uint64_t dirty : 1; | ||
uint64_t huge_page : 1; | ||
uint64_t global : 1; | ||
uint64_t available : 3; | ||
uint64_t physical_address : 52; | ||
} __attribute__((packed)) pte_t; | ||
|
||
// Struct for a page map level | ||
typedef struct PageMapLevel { | ||
pte_t entries[512]; | ||
} __attribute__((packed)) pml_t; | ||
|
||
class PhysicalMemoryManager{ | ||
|
||
private: | ||
const uint8_t ROW_BITS = { 64 }; | ||
|
||
uint64_t* m_bit_map; | ||
uint32_t m_total_entries; | ||
uint32_t m_bitmap_size; | ||
uint32_t m_used_frames; | ||
uint64_t m_memory_size; | ||
|
||
uint64_t m_anonymous_memory_physical_address; | ||
uint64_t m_anonymous_memory_virtual_address; | ||
|
||
multiboot_mmap_entry* m_mmap; | ||
multiboot_tag_mmap* m_mmap_tag; | ||
|
||
uint64_t* m_pml4_root_address; | ||
pte_t* m_pml4_root; | ||
|
||
bool m_initialized; | ||
|
||
// Table Management | ||
void create_table(pml_t* table, pml_t* next_table, size_t index); | ||
pte_t create_page_table_entry(uintptr_t address, size_t flags); | ||
bool table_has_entry(pml_t* table, size_t index); | ||
uint64_t* get_or_create_table(uint64_t* table, size_t index, size_t flags); | ||
uint64_t* get_table_if_exists(uint64_t* table, size_t index); | ||
|
||
|
||
uint64_t* get_bitmap_address(); | ||
|
||
public: | ||
|
||
PhysicalMemoryManager(unsigned long reserved, system::Multiboot* multiboot, uint64_t pml4_root[512]); | ||
~PhysicalMemoryManager(); | ||
|
||
|
||
// Vars | ||
static const uint32_t s_page_size = { 0x1000 }; // 4096 bytes | ||
uint64_t get_memory_size(); | ||
|
||
// Pml4 | ||
uint64_t* get_pml4_root_address(); | ||
|
||
// Frame Management | ||
void* allocate_frame(); | ||
void free_frame(void* address); | ||
|
||
void* allocate_area(uint64_t start_address, size_t size); | ||
void free_area(uint64_t start_address, size_t size); | ||
|
||
// Map | ||
virtual_address_t* map(virtual_address_t* virtual_address, size_t flags); | ||
virtual_address_t* map(physical_address_t* physical, virtual_address_t* virtual_address, size_t flags); | ||
virtual_address_t* map(physical_address_t* physical, virtual_address_t* virtual_address, size_t flags, uint64_t* pml4_root); | ||
void map_area(virtual_address_t* virtual_address_start, size_t length, size_t flags); | ||
void map_area(physical_address_t* physical_address_start, virtual_address_t* virtual_address_start, size_t length, size_t flags); | ||
void identity_map(physical_address_t* physical_address, size_t flags); | ||
|
||
void unmap(virtual_address_t* virtual_address); | ||
void unmap(virtual_address_t* virtual_address, uint64_t* pml4_root); | ||
void unmap_area(virtual_address_t* virtual_address_start, size_t length); | ||
|
||
// Tools | ||
static size_t size_to_frames(size_t size); | ||
static size_t align_to_page(size_t size); | ||
static size_t align_up_to_page(size_t size, size_t s_page_size); | ||
static bool check_aligned(size_t size); | ||
bool is_mapped(uintptr_t physical_address, uintptr_t virtual_address); | ||
bool is_anonymous_available(size_t size); | ||
bool is_multiboot_reserved(uint64_t address); | ||
|
||
static PhysicalMemoryManager* s_current_manager; | ||
void clean_page_table(uint64_t* table); | ||
}; | ||
} | ||
|
||
} | ||
|
||
#endif // MAXOS_MEMORY_PHYSICAL_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// | ||
// Created by 98max on 2/11/2024. | ||
// | ||
|
||
#ifndef MAXOS_VIRTUAL_H | ||
#define MAXOS_VIRTUAL_H | ||
|
||
#include <stdint.h> | ||
#include <stddef.h> | ||
#include <memory/physical.h> | ||
|
||
namespace MaxOS { | ||
namespace memory { | ||
|
||
|
||
typedef enum VirtualFlags { | ||
// 0 - (1 << 8) are reserved for the page flags | ||
Reserve = (1 << 9), | ||
|
||
} virtual_flags_t; | ||
|
||
typedef struct VirtualMemoryChunk{ | ||
uintptr_t start_address; | ||
size_t size; | ||
size_t flags; | ||
|
||
} virtual_memory_chunk_t; | ||
|
||
typedef struct VirtualMemoryRegion{ | ||
virtual_memory_chunk_t chunks[(PhysicalMemoryManager::s_page_size / sizeof(virtual_memory_chunk_t) - 1)]; | ||
struct VirtualMemoryRegion* next; | ||
|
||
} __attribute__((packed)) virtual_memory_region_t; | ||
|
||
class VirtualMemoryManager{ | ||
|
||
private: | ||
uint64_t * m_pml4_root_address; | ||
uint64_t * m_pml4_root_physical_address; | ||
PhysicalMemoryManager* m_physical_memory_manager; | ||
bool m_is_kernel; | ||
|
||
virtual_memory_region_t* m_first_region; | ||
virtual_memory_region_t* m_current_region; | ||
size_t m_current_chunk; | ||
size_t m_next_available_address; | ||
|
||
static const size_t s_chunks_per_page = (PhysicalMemoryManager::s_page_size / sizeof(virtual_memory_chunk_t) - 1); | ||
static const size_t s_reserved_space = 0x138000000; | ||
|
||
void new_region(); | ||
|
||
public: | ||
VirtualMemoryManager(bool is_kernel); | ||
~VirtualMemoryManager(); | ||
|
||
void* allocate(size_t size, size_t flags); | ||
void* allocate(uint64_t address, size_t size, size_t flags); | ||
void free(void* address); | ||
|
||
size_t memory_used(); | ||
|
||
}; | ||
} | ||
} | ||
|
||
|
||
#endif // MAXOS_VIRTUAL_H |
Oops, something went wrong.