These are not the same regions as in the NUMA concept but are areas occupied by system ROM for example or by ACPI functions

When the system is booted, the regions found are displayed by the kernel function print_memory_map. [email protected]> dmesg

BIOS-provided physical RAM map:


eB20 eB20 eB20 eB20 eB20 eB20 eB20 eB20 eB20 eB20 eB20

0000000000000000 000000000009eB00 00000000000c0000 00000000000dB000 0000000000l00000 00000000l7cf0000 00000000l7cff000 00000000l7d00000 00000000l7eB0000 00000000ffB00000 00000000fff00000

000000000009eB00 00000000000a0000 00000000000cc000 0000000000l00000 00000000l7cf0000 00000000l7cff000 00000000l7d00000 00000000l7eB0000 00000000lB000000 00000000ffc00000 0000000l00000000






(ACPI data)






If this information is not provided by the BIOS (this may be the case on some older machines), the kernel itself generates a table to mark memory in the ranges 0-640 KiB and 1 MiBend as usable.

The kernel then analyzes the command line with parse_cmdline_early, concentrating on arguments like mem=XXX[KkmM], highmem=XXX[kKmM], or memmap=XXX[KkmM]""@XXX[KkmM] arguments. The administrator can overwrite the size of available memory or manually define memory areas if the kernel calculates an incorrect value or is provided with a wrong value by the BIOS. This option is only of relevance on older computers. highmem= permits overwriting of the highmem size value detected. It can be used on machines with a very large RAM configuration to limit available RAM size — as it sometimes yields performance gains.

11There are not only ''normal'' IA-32 computers but also custom products of Silicon Graphics and NCR that, although they consist mainly of standard components, take a different approach to some things — including memory detection. Because these machines are either very old (Voyager from NCR) or not in widespread use (Visual Workstation from SGI), I won't bother with their oddities.

The next major step is performed in setup_memory of which there are two versions; one for systems with contiguous memory (in arch/x86/kernel/setup_32.c) and one for machines with discontiguous memory (in arch/x86/mm/discontig_32.c). They both have the same effect although their implementations differ.

□ The number of physical pages available (per node) is determined.

□ The bootmem allocator is initialized (Section 3.4.3 describes the implementation of the allocator in detail).

□ Various memory areas are then reserved, for instance, for the initial RAM disk needed when running the first userspace processes.

paging_init initializes the kernel page tables and enables paging since it is not active by default on IA-32 machines.12 Execute Disable Protection is also enabled if supported by the processor and if the kernel was compiled with PAE support; unfortunately, the feature is otherwise not available. By calling pagetable_init, the function also ensures that the direct mapping of physical memory into the kernel address space is initialized. All page frames in low memory are directly mapped to the virtual memory region above PAGE_OFFSET. This allows the kernel to address a good part of the available memory without having to deal with page tables anymore. More details about paging_init and the whole mechanism behind it are discussed below.

Calling zone_sizes_init initializes the pgdat_t instances of all nodes of the system. First a comparatively simple list of the available physical memory is prepared using add_active_range. The architecture-independent function free_are_init_nodes then uses this information to prepare the full-blown kernel data structures. Since this is a very important step that has numerous implications for how the kernel manages page frames at run time, it is discussed in more detail in Section 3.5.3.

Notice that the memory-related initialization sequence is quite similar on AMD64 machines, as the code flow diagram in Figure 3-13 shows.

The basic memory setup does not require any machine-type-specific handling, but can always be done with setup_memory_region. Information about the available RAM is given by the so-called E820 map supplied from the BIOS. After parsing the command-line options relevant for the early boot process, a simple list of the available memory is created by add_active called from e820_register_active_region, which, in turn, just walks over the information provided by parsing the E820 map above.

The kernel then calls init_memory_mapping to directly map the available physical memory into the virtual address space portion of the kernel starting from page_offset. contig_initmem_init is responsible to activate the bootmem allocator.

The last function in the list, paging_init, is actually a misnomer: It does not initialize paging, but has to deal with some set-up routines for sparse memory systems that are not interesting for our purposes. The important thing, however, is that the function also calls free_area_init_nodes, which is as in the IA-32 case responsible to initialize the data structures required to manage physical page frames by the kernel. Recall that this is an architecture-independent function and relies on the information provided by add_active_range as mentioned above. A detailed discussion of how free_area_init_nodes sets up memory follows in Section 3.5.3.

12All addresses are interpreted linearly if paging is not explicitly enabled.

setup_arch setup_memory_region parse_early_param

> add_active_range init_memory_mapping contig_initmem_init

free_area_init_nodes |

Figure 3-13: Code flow diagram for memory initialization on AMD64 systems.

Continue reading here: Initialization of Paging

Was this article helpful?

0 0