CLOSE
Updated on 30 Mar, 202617 mins read 33 views

The Physical Memory Manager (PMM) is one of the most foundational components is OS development – it manages actual RAM, not virtual abstractions.

What is the Physical Memory Management?

The Physical Memory Manager (PMM) is responsible for:

  • Tracking which parts of RAM are free/used
  • Allocating and freeing physical memory blocks (frames/pages)
  • Providing memory to:
    • Kernel
    • Virtual Memory Manager (VMM)
    • Devices drivers (DMA, buffers)

The PMM doesn't manage individual bytes of memory, rather it keeps track of pages. A page is a fixed size determined by the MMU: in the case of x86 this is 4096 (0x1000) bytes.

 

Memory Layout at Boot

When the OS boots, RAM is NOT fully free.

Some regions are already occupied:

  • Kernel code/data
  • Bootloader
  • BIOS/UEFI structures
  • Reserved hardware regions

Example Memory Map

From BIOS (e.g., via E820):

0x00000000 - 0x0009FC00  → Usable
0x0009FC00 - 0x000A0000  → Reserved
0x00100000 - 0x7FFFFFFF  → Usable

PMM must:

  • Parse this map
  • Only manage usable regions

Basic Unit: Frames (Pages)

Physical memory is dividied into fixed-size blocks:

  • Usually 4 KB pages
  • Called:
    • Frames (physical)
    • Pages (virtual)

Example:

If RAM = 4 GB:

4GB / 4KB = ~1 million frames

Memory Map

We receive the memory map from the bootloader.

In the bios system most common function to get the memory map is int 0x15, eax = E820.

It returns a list of memory regions, each describing:

  • Base address
  • Size
  • Type

Memory Region Types

TypeMeaning
1Available (usable RAM)
2Reserved
3+ACPI / firmware / special

Building the Memory Map

The bootloader:

  1. Iteratively calls BIOS (E820)
  2. Stores entries in a buffer
  3. Tracks number of entries
  4. Passes:
    1. Pointer to memory map
    2. Entry count
    3. Total memory size

This becomes the contract between bootloader and kernel.

Data Structures Used

There are different ways on how to handle a PMM.

This is where design choices matter:

1 Bitmap (Most Common)

Idea:

Each frame = 1 bit

This is the simplest approach: one bit per page frame, where 0 = free and 1 = allocated. For a 4GiB machine (1,048,576 pages), this costs just 128 KB of RAM – negligible.

0 → free
1 → used (allocated)

Example:

Frame:  0 1 2 3 4 5 6 7
Bitmap: 1 0 0 1 1 0 0 0

Allocations:

Allocation is O(n) in the worst case – you must scan until you find a zero bit.

Freeing is O(1): just clear the bit.

  • Scan for first 0
  • Mark it 1

Pros:

  • Very space efficient, 1 bit per 4 KB
  • Simple

Cons:

  • Slow for large memory (linear scan)

2 Free List

Maintain a linked list of free frames.

Pos:

  • Fast allocation
  • Easy to implement

Cons:

  • Poor for large contiguous allocation
  • Fragmentation issues

3 Buddy Allocator (Advanced)

Splits memory into power-of-2 blocks:

  • 1 page
  • 2 pages
  • 4 pages

Pros:

  • Efficient merging (coalscing)
  • Good for contiguous memory

Cons:

  • More complex
  • Internal Fragmentation

Why Do We Need a Physical Memory Manager?

When your OS boots, memory is:

  • Partially used (kernel, BIOS, bootloader)
  • Reserved hardware regions
  • Fragmented
  • Unstructured

The bootloader gives us a memory map, but that's just information, not a management system.

Without a PMM:

  • You might overwrite your kernel
  • Allocate the same memory twice
  • Corrupt hardware-mapped regions

So, PMM must answer:

  • Which pages are free?
  • Which pages are reserved?
  • How do I allocate contiguous memory?
  • How do I avoid overwriting critical regions?

Core Design: Bitmap Allocator

We would use a bitmap-based allocator.

Concept:

Divide memory into fixed-size pages (usually 4 KB):

Physical Memory → [Page0][Page1][Page2]...[PageN]

Then track each page with a bit:

Bitmap → 1 0 1 0 0 1 ...
         ↑ ↑ ↑ ↑ ↑ ↑
         Used/Free

Bitmap tracks:

  • 1: allocated
  • 0 : free

Memory Representation:

Physical memory is divided into:

Frame 0 → 0x00000000
Frame 1 → 0x00001000
Frame 2 → 0x00002000
...

Each frame:

  • Size = PAGE_SIZE (usually 4096 bytes)

Bitmap Structure

A bitmap is stored in memory:

Bit index = Frame number

Example:

FrameBitStatus
01Used
10Free
21Used

Initialization Strategy

The PMM follows a safe-first initialization model:

Step 1: Assume All Memory is Used

The bitmap is initialized to:

111111111111111111...

This ensures:

  • No accidental use of invalid memory

Step 2: Free Valid Memory Regions

The kernel iterates over the bootloader-provded memory map:

  • For each region of type available (type = 1)
    • Corresponding bits are cleared

Result:

Used → Reserved regions
Free → Usable RAM

Step 3: Reserve Critical Regions

Even if marked “available”, certain regions must remain reserved:

  • Kernel image
  • Kernel stack
  • Memory bitmap itself
  • Low memory regions (BIOS / hardware)
  • Special addresses (e.g., null page)

Allocation Model

Bootloader Input

The OS receives a memory map:

[Base Address | Size | Type]

Types:

TypeMeaning
1Usable RAM
OthersReserved

Key Design Principle

A robust PMM does:

Assume all memory is unsafe -> explicitly mark safe regions as usable.

This avoids accidental corruption of critical memory.

 

Buy Me A Coffee

Leave a comment

Your email address will not be published. Required fields are marked *

Your experience on this site will be improved by allowing cookies Cookie Policy