![]() |
Max OS 0.3
|
Manages the physical memory of the system such as what pages are allocated/free and mapping of virtual to physical addresses. More...
#include <physical.h>
Public Member Functions | |
| PhysicalMemoryManager (system::Multiboot *multiboot) | |
| Constructs a PhysicalMemoryManager. Unmaps the lower kernel and sets up the bitmap for physical memory management. Reserves the kernel and the multiboot regions. | |
| uint64_t | memory_size () const |
| Gets total the memory size available for use (allocated or not) | |
| uint64_t | memory_used () const |
| Gets the memory currently used. | |
| uint64_t * | pml4_root_address () |
| Gets the pml4 root address for the kernel. | |
| void * | allocate_frame () |
| Allocates a physical page of memory, if the PMM is not initalise it will use the anon memory instead of the bitmap. | |
| void | free_frame (void *address) |
| Frees a frame in the bit map. | |
| void * | allocate_area (uint64_t start_address, size_t size) |
| Allocate an area of physical memory (ie reserve it) | |
| void | free_area (uint64_t start_address, size_t size) |
| Frees an area of physical memory. | |
| virtual_address_t * | map (virtual_address_t *virtual_address, size_t flags) |
| Allocates a physical address to a virtual address. | |
| virtual_address_t * | map (physical_address_t *physical, virtual_address_t *virtual_address, size_t flags) |
| Maps a physical address to a virtual address, using the kernel's pml4 table. | |
| virtual_address_t * | map (physical_address_t *physical, virtual_address_t *virtual_address, size_t flags, uint64_t *pml4_root) |
| Maps a physical address to a virtual address. | |
| void | map_area (virtual_address_t *virtual_address_start, size_t length, size_t flags) |
| Allocates a new area physical memory to a area virtual address. | |
| void | map_area (physical_address_t *physical_address_start, virtual_address_t *virtual_address_start, size_t length, size_t flags) |
| Maps an area of physical memory to a virtual address. | |
| void | identity_map (physical_address_t *physical_address, size_t flags) |
| Maps a physical address to its virtual address counter-part. | |
| void | unmap (virtual_address_t *virtual_address) |
| Unmaps a virtual address using the kernel's pml4 table. | |
| void | unmap (virtual_address_t *virtual_address, uint64_t *pml4_root) |
| Unmaps a virtual address. | |
| void | unmap_area (virtual_address_t *virtual_address_start, size_t length) |
| Unmaps an area of virtual memory. | |
| void | reserve (uint64_t address) |
| Reserves a physical address. | |
| void | reserve (uint64_t address, size_t size, const char *="Unknown") |
| Reserves an area of physical memory. | |
| void | reserve_kernel_regions (system::Multiboot *multiboot) |
| Reserves the kernel, multiboot modules, mmap regions and higher half mapping regions in the physical memory manager so that those pages arent overwritten later. | |
| 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) | |
| bool | is_mapped (uintptr_t physical_address, uintptr_t virtual_address, uint64_t *pml4_root) |
| Checks if a physical address is mapped to a virtual address. | |
| void | change_page_flags (virtual_address_t *virtual_address, size_t flags, uint64_t *pml4_root) |
| Changes the flags of a page. | |
Static Public Member Functions | |
| static void | unmap_lower_kernel () |
| Unmaps the kernel physical memory from the lower half that was set up during the kernel boot. | |
| static size_t | size_to_frames (size_t size) |
| Converts a size to the number of frames. | |
| static size_t | align_to_page (size_t size) |
| Aligns a size to the page size. | |
| static size_t | align_direct_to_page (size_t size) |
| Aligns a address to the page size. | |
| static size_t | align_up_to_page (size_t size, size_t s_page_size) |
| Aligns a size up to the page size. | |
| static bool | check_aligned (size_t size) |
| Checks if an address is aligned. | |
| static void | clean_page_table (uint64_t *table) |
| Cleans a page table (fills it with 0 or null entries) | |
| static void * | to_higher_region (uintptr_t physical_address) |
| Converts a physical address to a higher region address if it is in the lower region using the higher half kernel offset. | |
| 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 half kernel offset. | |
| static void * | to_io_region (uintptr_t physical_address) |
| Converts a physical address to an IO region address if it is in the lower region using the higher half memory offset. | |
| 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 higher half direct map offset. | |
| static void * | from_dm_region (uintptr_t physical_address) |
| Converts a direct map region address to a physical address if it is in the higher region using the higher half direct map offset. | |
| static bool | in_higher_region (uintptr_t virtual_address) |
| Checks if a virtual address is in the higher region. | |
Static Public Attributes | |
| static PhysicalMemoryManager * | s_current_manager = nullptr |
| The current physical memory manager in use. | |
Manages the physical memory of the system such as what pages are allocated/free and mapping of virtual to physical addresses.
Definition at line 108 of file physical.h.
|
explicit |
Constructs a PhysicalMemoryManager. Unmaps the lower kernel and sets up the bitmap for physical memory management. Reserves the kernel and the multiboot regions.
| multiboot | The multiboot information structure to use for memory information such as the memory map. |
Definition at line 31 of file physical.cpp.
References _kernel_end, _kernel_physical_end, _kernel_size, multiboot_mmap_entry::addr, align_up_to_page(), MaxOS::system::CPU::check_nx(), MaxOS::Logger::DEBUG(), multiboot_tag_mmap::entries, multiboot_tag_mmap::entry_size, MaxOS::memory::HIGHER_HALF_DIRECT_MAP, MaxOS::Logger::INFO(), multiboot_mmap_entry::len, map(), memory_used(), MaxOS::system::Multiboot::mmap(), MaxOS::memory::PAGE_SIZE, MaxOS::memory::PRESENT, reserve_kernel_regions(), MaxOS::memory::ROW_BITS, s_current_manager, multiboot_tag_mmap::size, MaxOS::common::Spinlock::unlock(), unmap_lower_kernel(), and MaxOS::memory::WRITE.
Aligns a address to the page size.
| size | The address to align |
Definition at line 767 of file physical.cpp.
References MaxOS::memory::PAGE_SIZE.
Referenced by reserve().
Aligns a size to the page size.
| size | The size to align |
Definition at line 167 of file physical.cpp.
References MaxOS::memory::PAGE_SIZE.
Referenced by size_to_frames(), and MaxOS::memory::VirtualMemoryManager::VirtualMemoryManager().
Aligns a size up to the page size.
| size | The size to align |
| page_size | The page size to align to |
Definition at line 179 of file physical.cpp.
Referenced by MaxOS::memory::VirtualMemoryManager::allocate(), PhysicalMemoryManager(), and reserve().
Allocate an area of physical memory (ie reserve it)
| start_address | The start of the block |
| size | The size to allocate |
Definition at line 275 of file physical.cpp.
References ASSERT, MaxOS::common::Spinlock::lock(), MaxOS::memory::PAGE_SIZE, MaxOS::memory::ROW_BITS, size_to_frames(), and MaxOS::common::Spinlock::unlock().
| void * PhysicalMemoryManager::allocate_frame | ( | ) |
Allocates a physical page of memory, if the PMM is not initalise it will use the anon memory instead of the bitmap.
Definition at line 200 of file physical.cpp.
References multiboot_mmap_entry::addr, ASSERT, MaxOS::common::Spinlock::lock(), MaxOS::memory::PAGE_SIZE, MaxOS::memory::ROW_BITS, and MaxOS::common::Spinlock::unlock().
Referenced by map().
| void PhysicalMemoryManager::change_page_flags | ( | virtual_address_t * | virtual_address, |
| size_t | flags, | ||
| uint64_t * | pml4_root | ||
| ) |
Changes the flags of a page.
| virtual_address | The virtual address of the page |
| flags | The flags to set the page to |
| pml4_root | The address of the root pml to use |
Definition at line 847 of file physical.cpp.
Checks if an address is aligned.
| size | The address to check |
Definition at line 190 of file physical.cpp.
References MaxOS::memory::PAGE_SIZE.
Referenced by MaxOS::memory::VirtualMemoryManager::allocate().
Cleans a page table (fills it with 0 or null entries)
| table | The table to clean |
Definition at line 639 of file physical.cpp.
Referenced by MaxOS::memory::VirtualMemoryManager::VirtualMemoryManager().
Frees an area of physical memory.
| start_address | The start of the block |
| size | The size to free |
Definition at line 344 of file physical.cpp.
References MaxOS::common::Spinlock::lock(), MaxOS::memory::PAGE_SIZE, MaxOS::memory::ROW_BITS, size_to_frames(), and MaxOS::common::Spinlock::unlock().
Frees a frame in the bit map.
| address | The address to free |
Definition at line 256 of file physical.cpp.
References MaxOS::common::Spinlock::lock(), MaxOS::memory::PAGE_SIZE, MaxOS::memory::ROW_BITS, and MaxOS::common::Spinlock::unlock().
Converts a direct map region address to a physical address if it is in the higher region using the higher half direct map offset.
| virtual_address | The physical address in the direct map region |
Definition at line 945 of file physical.cpp.
References MaxOS::memory::HIGHER_HALF_DIRECT_MAP.
Referenced by reserve_kernel_regions().
| physical_address_t * PhysicalMemoryManager::get_physical_address | ( | virtual_address_t * | virtual_address, |
| uint64_t * | pml4_root | ||
| ) |
Gets the physical address from a virtual address (if it exists)
| virtual_address | The virtual address to get the physical address from |
| pml4_root | The address of the root pml to use |
Definition at line 829 of file physical.cpp.
Referenced by is_mapped().
| void PhysicalMemoryManager::identity_map | ( | physical_address_t * | physical_address, |
| size_t | flags | ||
| ) |
Maps a physical address to its virtual address counter-part.
| physical_address | The physical address to map |
| flags | The flags to set the mapping to |
Definition at line 582 of file physical.cpp.
References map().
Checks if a virtual address is in the higher region.
| virtual_address | The virtual address |
Definition at line 961 of file physical.cpp.
Referenced by map(), and MaxOS::system::CPU::prepare_for_panic().
| bool PhysicalMemoryManager::is_mapped | ( | uintptr_t | physical_address, |
| uintptr_t | virtual_address, | ||
| uint64_t * | pml4_root | ||
| ) |
Checks if a physical address is mapped to a virtual address.
| physical_address | The physical address to check |
| virtual_address | The virtual address to check |
| pml4_root | The pml4 table to use |
Definition at line 870 of file physical.cpp.
References get_physical_address().
| virtual_address_t * PhysicalMemoryManager::map | ( | physical_address_t * | physical_address, |
| virtual_address_t * | virtual_address, | ||
| size_t | flags | ||
| ) |
Maps a physical address to a virtual address, using the kernel's pml4 table.
| physical_address | The physical address to map |
| virtual_address | The virtual address to map to |
| flags | The flags to set the mapping to |
Definition at line 496 of file physical.cpp.
References map().
| virtual_address_t * PhysicalMemoryManager::map | ( | physical_address_t * | physical_address, |
| virtual_address_t * | virtual_address, | ||
| size_t | flags, | ||
| uint64_t * | pml4_table | ||
| ) |
Maps a physical address to a virtual address.
| physical_address | The physical address |
| virtual_address | The virtual address |
| flags | The flags to set the mapping to |
| pml4_table | The pml4 table to use |
Definition at line 511 of file physical.cpp.
References in_higher_region(), and MaxOS::memory::USER.
| virtual_address_t * PhysicalMemoryManager::map | ( | virtual_address_t * | virtual_address, |
| size_t | flags | ||
| ) |
Allocates a physical address to a virtual address.
| virtual_address | The virtual address |
| flags | The flags to set the mapping to |
Definition at line 538 of file physical.cpp.
References allocate_frame(), and map().
Referenced by identity_map(), MaxOS::hardwarecommunication::IOAPIC::IOAPIC(), MaxOS::hardwarecommunication::LocalAPIC::LocalAPIC(), map(), map(), map_area(), map_area(), and PhysicalMemoryManager().
| void PhysicalMemoryManager::map_area | ( | physical_address_t * | physical_address_start, |
| virtual_address_t * | virtual_address_start, | ||
| size_t | length, | ||
| size_t | flags | ||
| ) |
Maps an area of physical memory to a virtual address.
| physical_address_start | The start of the physical address |
| virtual_address_start | The start of the virtual address |
| length | The length of the area |
| flags | The flags to set the mapping to |
Definition at line 568 of file physical.cpp.
References map(), MaxOS::memory::PAGE_SIZE, and size_to_frames().
| void PhysicalMemoryManager::map_area | ( | virtual_address_t * | virtual_address_start, |
| size_t | length, | ||
| size_t | flags | ||
| ) |
Allocates a new area physical memory to a area virtual address.
| virtual_address_start | The start of the virtual address |
| length | The length of the area |
| flags | The flags to set the mapping to |
Definition at line 552 of file physical.cpp.
References map(), MaxOS::memory::PAGE_SIZE, and size_to_frames().
| uint64_t PhysicalMemoryManager::memory_size | ( | ) | const |
Gets total the memory size available for use (allocated or not)
Definition at line 746 of file physical.cpp.
| uint64_t PhysicalMemoryManager::memory_used | ( | ) | const |
Gets the memory currently used.
Definition at line 756 of file physical.cpp.
References MaxOS::memory::PAGE_SIZE.
Referenced by PhysicalMemoryManager().
| uint64_t * PhysicalMemoryManager::pml4_root_address | ( | ) |
Gets the pml4 root address for the kernel.
Definition at line 736 of file physical.cpp.
Reserves a physical address.
| address | The address to reserve |
Definition at line 777 of file physical.cpp.
References MaxOS::memory::PAGE_SIZE, and reserve().
Referenced by MaxOS::hardwarecommunication::LocalAPIC::LocalAPIC(), reserve(), and reserve_kernel_regions().
| void PhysicalMemoryManager::reserve | ( | uint64_t | address, |
| size_t | size, | ||
| const char * | type = "Unknown" |
||
| ) |
Reserves an area of physical memory.
| address | The start of the area |
| size | The size of the area |
| type | The name for the region being reserved (not required, logging purposes only, defaults to unkown) |
Definition at line 789 of file physical.cpp.
References align_direct_to_page(), align_up_to_page(), ASSERT, MaxOS::Logger::DEBUG(), MaxOS::common::Spinlock::lock(), MaxOS::memory::PAGE_SIZE, MaxOS::memory::ROW_BITS, and MaxOS::common::Spinlock::unlock().
| void PhysicalMemoryManager::reserve_kernel_regions | ( | system::Multiboot * | multiboot | ) |
Reserves the kernel, multiboot modules, mmap regions and higher half mapping regions in the physical memory manager so that those pages arent overwritten later.
| multiboot | The multiboot information structure to use for memory information such as the memory map. |
Definition at line 96 of file physical.cpp.
References multiboot_mmap_entry::addr, multiboot_tag_mmap::entries, multiboot_tag_mmap::entry_size, from_dm_region(), multiboot_mmap_entry::len, MaxOS::memory::PAGE_SIZE, reserve(), multiboot_tag_mmap::size, to_higher_region(), and to_lower_region().
Referenced by PhysicalMemoryManager().
Converts a size to the number of frames.
| size | The size to convert |
Definition at line 156 of file physical.cpp.
References align_to_page(), and MaxOS::memory::PAGE_SIZE.
Referenced by MaxOS::memory::VirtualMemoryManager::allocate(), allocate_area(), free_area(), MaxOS::memory::VirtualMemoryManager::load_physical_into_address_space(), map_area(), map_area(), unmap_area(), MaxOS::drivers::video::VideoElectronicsStandardsAssociation::VideoElectronicsStandardsAssociation(), and MaxOS::memory::VirtualMemoryManager::~VirtualMemoryManager().
Converts a physical address to a direct map region address if it is in the lower region using the higher half direct map offset.
| physical_address | The physical address |
Definition at line 930 of file physical.cpp.
References MaxOS::memory::HIGHER_HALF_DIRECT_MAP, and MaxOS::memory::HIGHER_HALF_OFFSET.
Referenced by MaxOS::processes::GlobalScheduler::load_multiboot_elfs(), MaxOS::drivers::video::VideoElectronicsStandardsAssociation::VideoElectronicsStandardsAssociation(), and MaxOS::memory::VirtualMemoryManager::VirtualMemoryManager().
Converts a physical address to a higher region address if it is in the lower region using the higher half kernel offset.
| physical_address | The physical address |
Definition at line 883 of file physical.cpp.
References MaxOS::memory::HIGHER_HALF_KERNEL_OFFSET.
Referenced by reserve_kernel_regions().
Converts a physical address to an IO region address if it is in the lower region using the higher half memory offset.
| physical_address | The physical address |
Definition at line 915 of file physical.cpp.
References MaxOS::memory::HIGHER_HALF_MEM_OFFSET.
Referenced by MaxOS::hardwarecommunication::AdvancedConfigurationAndPowerInterface::find(), MaxOS::hardwarecommunication::IOAPIC::IOAPIC(), and MaxOS::hardwarecommunication::LocalAPIC::LocalAPIC().
Converts a virtual address to a lower region address if it is in the higher region using the higher half kernel offset.
| virtual_address | The virtual address |
Definition at line 899 of file physical.cpp.
References MaxOS::memory::HIGHER_HALF_KERNEL_OFFSET.
Referenced by MaxOS::system::CPU::init_cores(), MaxOS::system::Multiboot::Multiboot(), reserve_kernel_regions(), and MaxOS::memory::VirtualMemoryManager::VirtualMemoryManager().
| void PhysicalMemoryManager::unmap | ( | virtual_address_t * | virtual_address | ) |
Unmaps a virtual address using the kernel's pml4 table.
| virtual_address | The virtual address to unmap |
Definition at line 593 of file physical.cpp.
References unmap().
Referenced by unmap(), and unmap_area().
| void PhysicalMemoryManager::unmap | ( | virtual_address_t * | virtual_address, |
| uint64_t * | pml4_root | ||
| ) |
Unmaps a virtual address.
| virtual_address | The virtual address to unmap |
| pml4_root | The pml4 table to use |
Definition at line 605 of file physical.cpp.
| void PhysicalMemoryManager::unmap_area | ( | virtual_address_t * | virtual_address_start, |
| size_t | length | ||
| ) |
Unmaps an area of virtual memory.
| virtual_address_start | The start of the area |
| length | The length of the area |
Definition at line 627 of file physical.cpp.
References MaxOS::memory::PAGE_SIZE, size_to_frames(), and unmap().
|
static |
Unmaps the kernel physical memory from the lower half that was set up during the kernel boot.
Definition at line 970 of file physical.cpp.
References p4_table.
Referenced by PhysicalMemoryManager().
|
inlinestatic |
The current physical memory manager in use.
Definition at line 185 of file physical.h.
Referenced by MaxOS::memory::VirtualMemoryManager::allocate(), MaxOS::processes::SharedMemory::close(), MaxOS::system::CPU::init_cores(), MaxOS::hardwarecommunication::IOAPIC::IOAPIC(), MaxOS::memory::VirtualMemoryManager::load_physical_into_address_space(), MaxOS::hardwarecommunication::LocalAPIC::LocalAPIC(), PhysicalMemoryManager(), MaxOS::processes::SharedMemory::SharedMemory(), MaxOS::drivers::video::VideoElectronicsStandardsAssociation::VideoElectronicsStandardsAssociation(), MaxOS::memory::VirtualMemoryManager::VirtualMemoryManager(), MaxOS::processes::Process::~Process(), and MaxOS::memory::VirtualMemoryManager::~VirtualMemoryManager().