My Kernel v0.1.0
Physical Memory Manager
Collaboration diagram for Physical Memory Manager:

Modules

 Internal structures and definitions
 Internal structures and definitions used by the PMM.
 

Data Structures

struct  page
 Represents a physical pageframe. More...
 

Macros

#define PMM_INVALID_PAGEFRAME   (0xFFFFFFFFUL)
 Error value returned by the PMM in case of errors.
 
#define TOTAL_PAGEFRAMES_COUNT   (ADDRESS_SPACE_SIZE / PAGE_SIZE)
 Total number of pageframes. More...
 
#define TO_PFN(_pageframe)   (((native_t)(_pageframe)) >> PAGE_SHIFT)
 Convert pageframe address to page frame number.
 
#define FROM_PFN(_pageframe)   ((_pageframe) << PAGE_SHIFT)
 Convert pageframe number to pageframe address.
 
#define pmm_allocate()   pmm_allocate_pages(PAGE_SIZE)
 Allocate a previously unused pageframe. More...
 

Enumerations

enum  page_flags { PAGE_AVAILABLE = BIT(0) , PAGE_COW = BIT(1) }
 Flags used for struct page 'flags' field. More...
 

Functions

static paddr_t page_address (const struct page *page)
 
static struct pagepfn_to_page (unsigned int pfn)
 
static struct pageaddress_to_page (paddr_t addr)
 
struct pagepage_get (struct page *page)
 Increase the page's refcount.
 
void page_put (struct page *page)
 Decrease the page's refcount. More...
 
static bool page_is_cow (struct page *page)
 
bool pmm_init (struct multiboot_info *)
 Initialize the Physical Memory Mapper. More...
 
paddr_t pmm_allocate_pages (size_t size)
 Allocate previously unused pageframes. More...
 
void pmm_free_pages (paddr_t pageframe, size_t size)
 Release previously allocated contiguous pageframes.
 

Variables

struct page pmm_pageframes [TOTAL_PAGEFRAMES_COUNT]
 The array of all existing pageframes. More...
 

Detailed Description

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.

Macro Definition Documentation

◆ pmm_allocate

#define pmm_allocate ( )    pmm_allocate_pages(PAGE_SIZE)
Returns
The pageframe's physical address, PMM_INVALID_PAGEFRAME on error

◆ TOTAL_PAGEFRAMES_COUNT

#define TOTAL_PAGEFRAMES_COUNT   (ADDRESS_SPACE_SIZE / PAGE_SIZE)

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).

Enumeration Type Documentation

◆ page_flags

enum page_flags
Enumerator
PAGE_AVAILABLE 

This page has not been allocated.

PAGE_COW 

Currently used in a CoW mapping.

Function Documentation

◆ 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
sizeThe size of the area to allocate (must me a multiple of PAGE_SIZE)
flagsAllocation 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_infoThe 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.

Variable Documentation

◆ pmm_pageframes

struct page pmm_pageframes[TOTAL_PAGEFRAMES_COUNT]
extern
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).