Registering Regions on IA32

Besides calling add_active_range, the function zone_sizes_init stores the boundaries of the different memory zones in terms of page frames.

arch/x86/kernel/setup_32.c void _init zone_sizes_init(void)

unsigned long max_zone_pfns[MAX_NR_ZONES]; memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); max_zone_pfns[ZONE_DMA] =

virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; max_zone_pfns[ZONE_NORMAL] = max_low_pfn; #ifdef CONFIG_HIGHMEM

max_zone_pfns[ZONE_HIGHMEM] = highend_pfn; add_active_range(0, 0, highend_pfn);

#endif free_area_init_nodes(max_zone_pfns);

MAX_DMA_ADDRESS is the highest suitable memory address for DMA operations. The constant is declared as page_offset+0x1000000. Recall that the physical pages are mapped into the virtual starting from page_offset, and the first 16 MiB — hexadecimal 0x1000000 — are suitable for DMA operations. Conversion with virt_to_phys yields the address in physical memory, and shifting right by page_shift bits effectively divides this figure by the page size and produces the number of pages that can be used for DMA. Unsurprisingly, the result is 4,096 since IA-32 uses pages of 4 KiB.

max_low_pfn and highend_pfn are global constants to specify the highest page number in the low (usually < 896 MiB if 3 : 1 split of the address space is used) and high memory ranges that were filled before.

Notice that free_area_init_nodes will combine the information in early_mem_map and max_zone_pfns: The active ranges for each memory region are selected, and architecture-independent data structures are constructed.

Continue reading here: Registering Regions on AMD64

Was this article helpful?

0 0