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:
- Directly from BIOS (legacy): via INT 15h E820h call, returns e820 memory map table
- 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:
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
- early_init_fdt_scan_reserved_mem() — scan Device Tree for reserved memory
- e820__memory_setup() — parse e820 table
- memblock_add() — add memory regions to memblock.memory
- memblock_reserve() — reserve kernel code/data, initrd
Final memblock structure:
- memory: available physical memory regions (DRAM)
- reserved: allocated/reserved regions
Comments