Physical Memory Manager
The PMM is responsible for allocating and freeing new memory pageframes. These pages are then used by the Virtual Memory Manager (e.g. UNIX's mmap) to return new (or free) mapped virtual addresses to the caller.
The PMM should never interact with the virtual address space, this is the responsabillity of the VMM only.
Design
A physical pageframe is represented by a struct page. The PMM keeps track of every existing physical page inside a statically allocated array. This array is indexed using the page's "pageframenumber". A pageframe number (PFN) is simply the page's physical address divided by the architecture's page size.
- Todo:
- TODO: Implement a buddy Allocator The buddy allocator is less memory efficient, but way faster when it comes to retrieving available pages.
◆ pmm_allocate
- Returns
- The pageframe's physical address, PMM_INVALID_PAGEFRAME on error
◆ TOTAL_PAGEFRAMES_COUNT
This is the theorical total number of pageframes available inside the whole address space.
BUT, not all pageframes are necessarily available (usable for memory allocation). Some are reserved, used for ACPI, plus RAM is not guaranteed to be contiugous.
This constant should ONLY be used as a compile-time known theoretical reference value (e.g. the physical memory manager's bit map size).
◆ page_flags
| Enumerator |
|---|
| PAGE_AVAILABLE | This page has not been allocated.
|
| PAGE_COW | Currently used in a CoW mapping.
|
◆ address_to_page()
| static struct page * address_to_page |
( |
paddr_t |
addr | ) |
|
|
inlinestatic |
- Returns
- The page struct corresponding to a physical address's pageframe
◆ page_address()
| static paddr_t page_address |
( |
const struct page * |
page | ) |
|
|
inlinestatic |
- Returns
- A page's physical address
◆ page_is_cow()
| static bool page_is_cow |
( |
struct page * |
page | ) |
|
|
inlinestatic |
- Returns
- whether the page is part of a CoW mapping.
◆ page_put()
| void page_put |
( |
struct page * |
page | ) |
|
If it reaches 0, the page is released.
◆ pfn_to_page()
| static struct page * pfn_to_page |
( |
unsigned int |
pfn | ) |
|
|
inlinestatic |
- Returns
- The page struct corresponding to a pageframe number
◆ pmm_allocate_pages()
| paddr_t pmm_allocate_pages |
( |
size_t |
size | ) |
|
@info The returned pageframes are guaranteed to be contiguous
- Parameters
-
| size | The size of the area to allocate (must me a multiple of PAGE_SIZE) |
| flags | Allocation flags |
- Returns
- The pageframe range's physical address, PMM_INVALID_PAGEFRAME on error
◆ pmm_init()
| bool pmm_init |
( |
struct multiboot_info * |
mbt | ) |
|
- Identify all the available page frames
- Locate the first page frame
The list of available page frames is retrieved from the memory map passed by our multiboot compliant bootloader.
- Parameters
-
| multiboot_info | The information struct passed by the multiboot-compliant bootloader to our entry function |
- Warning
- This function should be called only once when starting the kernel. Otherwise it will overwrite the content of the underlying structures.
◆ pmm_pageframes
- Note
- The arrays's size is hardcoded to be able to fit each and every pageframes (even though only part of them will be available at runtime).
The array of all existing pageframes.
- Note
- The arrays's size is hardcoded to be able to fit each and every pageframes (even though only part of them will be available at runtime).