Skip to content

Day90 - Kernel Memory Management Internals

Goal

Understand how the Linux kernel manages physical memory internally, how the Buddy Allocator allocates and merges physical pages, and how kmalloc() is ultimately backed by the kernel memory management subsystem.


Why Kernel Memory Management?

Unlike user-space applications, the Linux kernel cannot rely on the standard C library allocator. It must manage physical memory directly while supporting different execution contexts, allocation constraints, and performance requirements.

Kernel memory allocation is therefore organized into multiple layers, each responsible for a different level of abstraction.

Kernel Driver


kmalloc()


SLUB


Buddy Allocator


Physical Pages


Physical RAM

Physical Memory Pages

Linux manages physical memory in units of pages rather than individual bytes.

Typical page size:

  • 4 KB on most architectures

Each physical page is represented by a corresponding struct page, which stores metadata describing that page.


struct page

Every physical page has an associated metadata structure.

For this lab, a simplified version was implemented:

struct page {
    uint32_t pfn;
    bool block_head;
    bool allocated;
    uint32_t order;
};

The implementation models:

  • Physical Page Frame Number (PFN)
  • Allocation state
  • Buddy block ownership
  • Allocation order

Buddy Allocator

The Buddy Allocator manages contiguous physical page blocks whose sizes are powers of two.

For example:

Order Pages
0 1
1 2
2 4
3 8
4 16
5 32
6 64

When the requested order is unavailable, a larger block is recursively split until the desired order is reached.


Split

A larger free block can be recursively divided into two equal-sized buddy blocks.

Example:

Order6


Order5 + Order5


Order4 + Order4


Order3 + Order3


Order2 + Order2

Only the required number of splits is performed.


Merge

When a block is freed, the allocator checks whether its buddy block is also free.

If both buddy blocks have the same order, they are merged into the next higher order.

This process continues recursively until:

  • the buddy is allocated, or
  • the maximum order is reached.

Buddy Address Calculation

A buddy block can be located directly from the Page Frame Number.

buddy_pfn = pfn ^ (1 << order)

This works because buddy blocks always have sizes that are powers of two.


Memory Fragmentation

The Buddy Allocator continuously merges adjacent free blocks whenever possible.

Although repeated split and merge operations occur, these operations only modify allocator metadata and free lists rather than moving actual page contents.

Maintaining larger contiguous free blocks is more important than avoiding split/merge operations because it reduces memory fragmentation and improves the success rate of higher-order allocations.


Relationship between Buddy Allocator and SLUB

The Buddy Allocator manages physical pages.

SLUB manages fixed-size objects built on top of those pages.

The overall allocation path is:

Driver


kmalloc()


SLUB


Buddy Allocator


Physical RAM

Lab Summary

Lab1

Implemented a simplified physical page manager.

Verified:

  • Physical page initialization
  • struct page
  • Initial Order 6 free block

Lab2

Implemented recursive page splitting.

Verified:

  • alloc_pages()
  • Allocation order
  • Buddy split

Lab3

Verified Buddy allocation policy.

Verified:

  • Existing block reuse
  • Split on demand

Lab4

Implemented recursive buddy merging.

Verified:

  • Buddy detection
  • Recursive merge
  • Recovery to the highest possible order

Summary

Today we moved beyond the kmalloc() API and explored the internal physical memory management used by the Linux kernel.

A simplified Buddy Allocator was implemented to demonstrate:

  • Physical page management
  • Allocation orders
  • Buddy split
  • Buddy merge
  • Memory fragmentation handling

This provides the foundation for understanding how higher-level allocators such as SLUB obtain physical pages.


Next

Day91 will continue with the Linux SLUB allocator, including:

  • kmem_cache
  • Slab
  • Object allocation
  • Cache management
  • Relationship between SLUB and kmalloc()