Skip to content

Day93 - vmalloc() Internals

Objective

Learn how Linux vmalloc() provides virtually contiguous memory by mapping multiple independent physical pages into a continuous virtual address range.

In this lab, we build a simplified vmalloc() simulator on top of the Buddy Allocator and compare its behavior with the real Linux kernel implementation.


Learning Objectives

After completing this lab, you should understand:

  • Why vmalloc() exists
  • Difference between kmalloc() and vmalloc()
  • Virtually contiguous vs physically contiguous memory
  • Virtual address management
  • Physical page mapping
  • Address translation with vmalloc_to_page()
  • Relationship between vmalloc() and the Buddy Allocator

Lab Architecture

                vmalloc()
        +----------------------+
        |   vmalloc_area       |
        +----------------------+
        | Virtual Address      |
        | Size                 |
        | struct page *[]      |
        +----------------------+
             Buddy Allocator
              Physical Pages

Unlike kmalloc(), each mapped page may come from a different physical location.


Lab 1 - Basic Allocation and Free

Goal

Understand the lifecycle of a vmalloc allocation.

Verify

  • vmalloc()
  • vfree()
  • Virtual address allocation
  • Page rounding
  • Area insertion/removal

Example:

vmalloc(1)


1 page allocated


Virtual Address
0x10000000

Lab 2 - Virtual Address Translation

Goal

Implement and verify vmalloc_to_page().

The translation flow is:

Virtual Address
Find vmalloc area
Calculate page index
struct page
PFN

Verify:

  • First page
  • Second page
  • Page boundary
  • Invalid addresses
  • Translation after vfree()

Lab 3 - Physically Non-contiguous Pages

Goal

Demonstrate that contiguous virtual memory does not require contiguous physical memory.

The lab intentionally fragments physical memory before calling vmalloc().

Example:

Virtual Range

0x10000000
0x10001000


PFN 1
PFN 3

Although the PFNs are not contiguous, the virtual address range remains continuous.


Lab 4 - Linux Kernel Verification

Goal

Compare the simulator with the real Linux kernel.

Kernel APIs:

  • vmalloc()
  • vmalloc_to_page()
  • page_to_pfn()
  • vfree()

Typical output:

Virtual Range

ffffc000825b8000
ffffc000825bc000
ffffc000825c0000
ffffc000825c4000

PFNs

229847
2728
33491
66084

The virtual addresses increase by one PAGE_SIZE, while the PFNs are not necessarily contiguous.

Note

The simulator uses a 4 KiB page size, while the Raspberry Pi 5 kernel used in this lab is configured with a 16 KiB page size.

Although the page size differs, both implementations follow the same address translation principle.


Key Takeaways

  • kmalloc() provides physically contiguous memory.
  • vmalloc() provides virtually contiguous memory.
  • vmalloc() allocates pages individually from the Buddy Allocator.
  • Virtual addresses remain contiguous even when physical pages are scattered.
  • vmalloc_to_page() translates a virtual address into its backing physical page.