I used to draw a memory distribution chart with some macro definitions of kernel memory management.
Such as vmalloc_start, vmalloc_end, and fixaddr_start.
I always thought that these values had more or less errors in the actual kernel. I did not expect to read them a few days ago.
They are completely consistent.
To calculate the total vmalloc size, we think that 1 GB of kernel space starts from 0.
First, my physical memory exceeds 896 MB, so high_memory is 896 MB.
8 m holes are used to capture out-of-bounds memory access, so vmalloc_start is at 896 m + 8 m = 904 m
Next we will calculate vmalloc_end.
The top part is a memory hole, followed by a fixed ing area. For the distribution of this area, refer to the following enumeration.
Enum fixed_addresses {
Fix_hole,
Fix_vdso,
Fix_dbgp_base,
Fix_earlycon_mem_base,
# Ifdef config_x86_local_apic
Fix_apic_base,/* local (CPU) APIC) -- required for SMP or not */
# Endif
# Ifdef config_x86_io_apic
Fix_io_apic_base_0,
Fix_io_apic_base_end = fix_io_apic_base_0 + MAX_IO_APICS-1,
# Endif
# Ifdef config_x86_visws_apic
Fix_co_cpu,/* cobalt timer */
Fix_co_apic,/* cobalt APIC redirection table */
Fix_li_pcia,/* Lithium PCI bridge */
Fix_li_pcib,/* Lithium PCI bridge B */
# Endif
# Ifdef config_x86_f00f_bug
Fix_f00f_idt,/* virtual mapping for IDT */
# Endif
# Ifdef config_x86_cyclone_timer
Fix_cyclone_timer,/* cyclone timer register */
# Endif
Fix_kmap_begin,/* Reserved PTE's for temporary kernel mappings */
Fix_kmap_end = fix_kmap_begin + (km_type_nr * nr_cpus)-1,
# Ifdef config_pci_mmconfig
Fix_pcie_mcfg,
# Endif
# Ifdef config_paravirt
Fix_paravirt_bootmap,
# Endif
_ End_of_permanent_fixed_addresses,
/*
* 256 temporary boot-time mappings, used by early_ioremap (),
* Before ioremap () is functional.
*
* We round it up to the next 256 pages boundary so that we
* Can have a single PGD entry and a single PTE table:
*/
# Define nr_fix_btmaps 64
# Define fix_btmaps_slots 4
Fix_btmap_end = _ end_of_permanent_fixed_addresses + 256-
(_ End_of_permanent_fixed_addresses & 255 ),
Fix_btmap_begin = fix_btmap_end + nr_fix_btmaps * fix_btmaps_slots-1,
Fix_wp_test,
# Ifdef config_acpi
Fix_acpi_begin,
Fix_acpi_end = fix_acpi_begin + fix_acpi_pages-1,
# Endif
# Ifdef config_provide_ohci1394_dma_init
Fix_ohci1394_base,
# Endif
_ End_of_fixed_addresses
};
Each enumeration represents one or more pages,
Except for nr_cpus, we take 1, and the maximum values of all others cannot exceed 1 K pages.
That is to say, the fixed ing cannot exceed 4 MB
Next is the permanent ing area. Let's look at the starting address definition of the permanent kernel ing.
# Define pkmap_base (fixaddr_boot_start-page_size * (last_pkmap + 1) & pmd_mask)
That is to say, the starting address of the permanent kernel ing is 4 m aligned under the fixed kernel ing-4 m,
As we have seen above, the fixed kernel ing is smaller than 4 m, so the starting address of the permanent kernel ing is at the 1g-8m position.
It occupies a piece of PMD, that is, 4 MB of space for x86.
Next is the vmalloc area. Let's look at the definition.
# Define vmalloc_end (pkmap_base-2 * page_size)
That is to say, the starting address of the permanent kernel ing. The next two pages are vmalloc_end.
Therefore, vmalloc_end = 1g-8m-2*4 K
The total vmalloc space is
Vmalloc_end-vmalloc_start
= 1g-8m-2*4 K-904 m
= 1048576 K-8192 K-8 K-925696 K
= 114680 K
Now look
CAT/proc/meminfo | grep vmalloctotal
Is it 114680 K?