As the kernel's memory layout source, the BIOS provides two sets of memory layout information, the first is the e820 memory map provided at legacy startup, and the other is
EFI memory map provided at EFI startup.
Before continuing, we need to know that the order in which x86 is started is, bios,grub,real mode,protect mode
Where real mode is the final step before entering the kernel, in this mode, depending on whether the system is legacy or EFI,
Gets the different memory map information.
First for legacy mode, it could be grub, or real mode code, based on the interface provided by the BIOS, to get
To the memory information and save it to the boot_params structure. (See Zero-page.txt)
Real mode gets the memory layout code in:
ARCH\X86\BOOT/MEMORY.C's detect_memory_e820 function, using the INT service provided by the BIOS, loops the execution
Intcall (0x15, &ireg, &oreg), get all e820 map information, save to Boot_params.e820_map.
For EFI startup mode, Realmode, it may be in the arch/x86/boot/compressed/eboot.c,
When Exit_boot, invoke the system Table->get_memory_map provided by EFI to obtain the memory layout information,
Then assign the value to Boot_params.efi_info.
After entering protect mode,
void __init Setup_arch (char **cmdline_p)
{
setup_memory_map ();
if (efi_enabled (efi_boot))
efi_init ();
}
With Boot_params, the associated memory layout initializes setup_memory_map:
The function passes through the Default_machine_specific_memory_setup,
First in the Sanitize_e820_map function, the Boot_params.e820_map is reordered, and then passed
Append_e820_map is added to the global variable data e820_map. Then E820_print_map.
Will print the memory layout of this e820 map, which is what we see:
[ 0.000000] e820:bios-provided physical RAM map:
[ 0.000000] bios-e820: [Mem 0X0000000000000000-0X0000000000057FFF] Usable
[ 0.000000] bios-e820: [Mem 0X0000000000058000-0X0000000000058FFF] Reserved
[ 0.000000] bios-e820: [Mem 0X0000000000059000-0X000000000009DFFF] Usable
Note that the above is only valid for legacy because he is checking for E820_map, and E820_map is a null pointer for EFI mode.
Then look at the EFI memory layout initialization, or in the Setup_arch:
if (!strncmp (char *) &boot_params.efi_info.efi_loader_signature,
efi32_loader_signature, 4)) {
set_bit (Efi_boot, &efi.flags);
} else if (!strncmp (char *) &boot_params.efi_info.efi_loader_signature,
efi64_loader_signature, 4)) {
set _bit (Efi_boot, &efi.flags);
Set_bit (Efi_64bit, &efi.flags);
}
if (efi_enabled (efi_boot))
efi_memblock_x86_reserve_range ();
if (efi_enabled (efi_boot))
efi_init ();
If there is an EFI flag in the Boot_params, then based on the Boot_params.efi_memmap to get the EFI partition information,
Finally, he joined the e820 table through E820_add_region. The specific process is:
Efi_init-> efi_memmap_init-> do_add_efi_memmap->
To being more specific, I found a hibernation error which complains of:
A very good summary of EFI Linux at:
https://lwn.net/Articles/632528/