B07 — From e820 to Memory Management Initialization: The memblock Allocator

Key insight: The kernel’s first step at boot is to figure out how much memory it has to manage.


How the Kernel Gets Memory Info

At boot, the kernel obtains physical memory info through two methods:

  1. Directly from BIOS (legacy): via INT 15h E820h call, returns e820 memory map table
  2. From bootloader (UEFI): UEFI bootloader has already initialized memory, passes via boot_params struct (Linux Boot Protocol)

Linux’s approach:

  • Boot params boot_params contains e820map
  • Kernel parses e820map, builds memblock
  • memblock eventually initializes the buddy system

memblock Data Structure

memblock is Linux’s early-stage memory allocator:

Bash
struct memblock {
    struct memblock_type memory;    // Available physical memory regions
    struct memblock_type reserved;  // Allocated/reserved regions
};

struct memblock_type {
    unsigned long cnt;              // Number of regions
    unsigned long max;             // Array capacity
    phys_addr_t total_size;        // Total size
    struct memblock_region *regions; // Region array
};

struct memblock_region {
    phys_addr_t base;              // Start address
    phys_addr_t size;             // Size
    unsigned long flags;          // MEMBLOCK_* flags
};

memblock Initialization Process

  1. early_init_fdt_scan_reserved_mem() — scan Device Tree for reserved memory
  2. e820__memory_setup() — parse e820 table
  3. memblock_add() — add memory regions to memblock.memory
  4. memblock_reserve() — reserve kernel code/data, initrd

Final memblock structure:

  • memory: available physical memory regions (DRAM)
  • reserved: allocated/reserved regions
Last modified: 2024年12月5日

Author

Comments

Write a Reply or Comment

Your email address will not be published.