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 → UsablePMM 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 framesMemory 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
| Type | Meaning |
|---|---|
| 1 | Available (usable RAM) |
| 2 | Reserved |
| 3+ | ACPI / firmware / special |
Building the Memory Map
The bootloader:
- Iteratively calls BIOS (
E820) - Stores entries in a buffer
- Tracks number of entries
- Passes:
- Pointer to memory map
- Entry count
- 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 0Allocations:
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/FreeBitmap tracks:
1: allocated0: 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 numberExample:
| Frame | Bit | Status |
|---|---|---|
| 0 | 1 | Used |
| 1 | 0 | Free |
| 2 | 1 | Used |
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 RAMStep 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:
| Type | Meaning |
|---|---|
| 1 | Usable RAM |
| Others | Reserved |
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.
Leave a comment
Your email address will not be published. Required fields are marked *


