UnnamedOS

Physical Memory Manager. More...

+ Collaboration diagram for PMM:

Macros

#define PAGE_SIZE   4096
 4KB pages
 
#define PAGE_SHIFT   12
 bits to shift to get page (2^12=4096)
 
#define MEMORY_SIZE   0x100000000
 4GB address space
 
#define TYPE_BITS   2
 number of bits per page entry
 
#define PAGE_NUMBER   (MEMORY_SIZE / PAGE_SIZE)
 total number of pages
 
#define ENTRIES   1024
 number of entries in a page table
 
#define PAGES_PER_DWORD   (32 / TYPE_BITS)
 pages in each bitmap entry
 
#define PAGES_BER_BYTE   (8 / TYPE_BITS)
 pages per bitmap entry byte
 
#define TYPE_MASK   (0xFFFFFFFF >> (32 - TYPE_BITS))
 calc 2^TYPE_BITS-1
 
#define BITMAP_INIT   0x55555555
 0b0101...01, use PMM_RESERVED
 
#define BIT_CHECK(val, bit)   (((val) >> (bit)) & 1)
 checks a bit in a given value
 
#define BITMAP_SET(idx)    (bitmap[(idx) / 32] |= 1 << ((idx) % 32))
 sets a bit in the memory bitmap
 
#define BITMAP_CLEAR(idx)    (bitmap[(idx) / 32] &= ~(1 << ((idx) % 32)))
 clears a bit in the memory bitmap
 

Enumerations

enum  pmm_flags_t { PMM_UNUSED, PMM_RESERVED, PMM_KERNEL, PMM_USER }
 information on who uses a page frame (needs to fit in TYPE_BITS)
 

Functions

static void pmm_bitmap_set (uint32_t idx, uint32_t value)
 Sets a bitmap entry to a value. More...
 
static uint32_t pmm_bitmap_get (uint32_t idx)
 Returns a bitmap entry. More...
 
static void pmm_use_kernel_memory ()
 Marks all kernel memory as used.
 
void pmm_init ()
 Initializes the PMM. More...
 
uint32_t pmm_get_page (void *ptr, uint32_t offset)
 Returns to which page a given memory address belongs. More...
 
void * pmm_get_address (uint32_t page, uint32_t offset)
 Returns a memory address belonging to a given page. More...
 
void pmm_use (void *ptr, size_t len, pmm_flags_t flags, char *tag)
 Marks page frames for a given memory range as used or unused. More...
 
static void * pmm_find_free (size_t len)
 Finds free page frames. More...
 
void * pmm_alloc (size_t len, pmm_flags_t flags)
 Allocates page frames. More...
 
void pmm_free (void *ptr, size_t len)
 Frees page frames. More...
 
pmm_flags_t pmm_check (void *ptr)
 Returns whether a page frame is used or unused. More...
 
void pmm_dump (void *ptr, size_t len)
 Dumps information on page frames for a given memory range. More...
 
uint32_t pmm_get_highest_kernel_page ()
 Returns the highest page used by the kernel. More...
 

Variables

static uint32_t bitmap [PAGE_NUMBER/PAGES_PER_DWORD]
 Holds information on used page frames. More...
 
static uint32_t highest_kernel_page = 0
 remember the highest kernel page
 
const void kernel_start
 start of the kernel section
 
const void kernel_end
 end of the kernel section
 
const void main_kernel_stack_end
 end of the main kernel stack
 
static void * main_kernel_stack_start
 start of the main kernel stack More...
 

Detailed Description

Physical Memory Manager.

The PMM allocates and frees physical page frames (blocks of 4KiB). It obtains an initial memory map from GRUB.

See also
http://wiki.osdev.org/Memory_management
http://wiki.osdev.org/Page_Frame_Allocation
http://www.lowlevel.eu/wiki/Physische_Speicherverwaltung
http://wiki.osdev.org/Detecting_Memory_(x86)

Function Documentation

void * pmm_alloc ( size_t  len,
pmm_flags_t  flags 
)

Allocates page frames.

Parameters
lenrequested number of consecutive free bytes
flagswhether to allocate for kernel or user space
Returns
the physical start address of the allocated memory range

Definition at line 183 of file pmm.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static uint32_t pmm_bitmap_get ( uint32_t  idx)
static

Returns a bitmap entry.

Parameters
idxindex into the bitmap
Returns
value of the bitmap entry, can be 9 to TYPE_MASK

Definition at line 72 of file pmm.c.

+ Here is the caller graph for this function:

static void pmm_bitmap_set ( uint32_t  idx,
uint32_t  value 
)
static

Sets a bitmap entry to a value.

Parameters
idxindex into the bitmap
valuevalue to set the entry to, can be 0 to TYPE_MASK

Definition at line 58 of file pmm.c.

+ Here is the caller graph for this function:

pmm_flags_t pmm_check ( void *  ptr)

Returns whether a page frame is used or unused.

Parameters
ptrthe physical address of the page frame to check
Returns
information on who uses the page

Definition at line 206 of file pmm.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void pmm_dump ( void *  ptr,
size_t  len 
)

Dumps information on page frames for a given memory range.

The dump is logged.

Parameters
ptrthe physical start address of the memory range
lenthe length of the memory range in bytes

Definition at line 215 of file pmm.c.

+ Here is the call graph for this function:

static void* pmm_find_free ( size_t  len)
static

Finds free page frames.

Parameters
lenrequested number of consecutive free bytes
Returns
the physical address of a suitable free memory range

Definition at line 160 of file pmm.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void pmm_free ( void *  ptr,
size_t  len 
)

Frees page frames.

Parameters
ptrthe physical start address of the memory range
lenthe length of the memory range in bytes

Definition at line 196 of file pmm.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void * pmm_get_address ( uint32_t  page,
uint32_t  offset 
)

Returns a memory address belonging to a given page.

Parameters
pagea page index
offsetnumber of bytes to add to the start of the page
Returns
the first address of the page (if given, the offset is added)

Definition at line 130 of file pmm.c.

+ Here is the caller graph for this function:

uint32_t pmm_get_highest_kernel_page ( )

Returns the highest page used by the kernel.

Returns
highest kernel page

Definition at line 235 of file pmm.c.

+ Here is the caller graph for this function:

uint32_t pmm_get_page ( void *  ptr,
uint32_t  offset 
)

Returns to which page a given memory address belongs.

Parameters
ptra physical or virtual address
offsetnumber of bytes to add to ptr
Returns
the page index that contains the address ptr

Definition at line 120 of file pmm.c.

+ Here is the caller graph for this function:

void pmm_init ( )

Initializes the PMM.

First assumes the whole memory is used, GRUB tells us about free memory.

Prevents that we allocate or dereference the null pointer or BIOS data by pmm_use()'ing the first page table.

Copies the multiboot structures somewhere into the kernel so we can overwrite lower memory in VM86 mode later. Because our kernel starts at 4 MiB (the 2nd page table) we reserved the first page table above so that the multiboot structures lie directly after the kernel.

After the structures were copied from lower memory, frees 0x100000-0x3FFFFF to not waste too much memory.

Definition at line 87 of file pmm.c.

+ Here is the call graph for this function:

void pmm_use ( void *  ptr,
size_t  len,
pmm_flags_t  flags,
char *  tag 
)

Marks page frames for a given memory range as used or unused.

Parameters
ptrthe physical start address of the memory range
lenthe length of the memory range in bytes
flagswhether to allocate or free page frames
taga short string for the debug log

Definition at line 141 of file pmm.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

uint32_t bitmap[PAGE_NUMBER/PAGES_PER_DWORD]
static

Holds information on used page frames.

We could save some space here with dynamic allocation if we had it. This way we use up 2MiB of memory.

Definition at line 40 of file pmm.c.

void* main_kernel_stack_start
static
Initial value:
= (void*) ((uintptr_t)
&main_kernel_stack_end - STACK_SIZE + 1)
const void main_kernel_stack_end
end of the main kernel stack

start of the main kernel stack

Definition at line 50 of file pmm.c.