难点
void __init bootmem_init(void)
{
unsigned long min, max;
min = PFN_UP(memblock_start_of_DRAM());
max = PFN_DOWN(memblock_end_of_DRAM());
/*
* Sparsemem tries to allocate bootmem in memory_present(), so must be
* done after the fixed reservations.
*/
arm64_memory_present();
sparse_init();
zone_sizes_init(min, max);
high_memory = __va((max << PAGE_SHIFT) - 1) + 1;
max_pfn = max_low_pfn = max;
}
1.bootmem_init------------------->arm64_memory_present------>memory_present
/* Record a memory area against a node. */
void __init memory_present(int nid, unsigned long start, unsigned long end)
{
unsigned long pfn;
start &= PAGE_SECTION_MASK;
mminit_validate_memmodel_limits(&start, &end);
for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION) {
unsigned long section = pfn_to_section_nr(pfn);
struct mem_section *ms;
sparse_index_init(section, nid);
set_section_nid(section, nid);
ms = __nr_to_section(section);
if (!ms->section_mem_map)
ms->section_mem_map = sparse_encode_early_nid(nid) |
SECTION_MARKED_PRESENT;
}
}
填充
mem_section 结构体数组
使用了memblock 分配内存,大小为4K,来放ms 执行的空间,并将齐放在mem_section 结构体数组中。
难点2:
sparse_init()
难点3
zone_sizes_init------->free_area_init_node------>free_area_init_core
node id 号,一般NUMA 为0,node_start_pfn ,起始的pfn,一般也为0,zones_size
上级函数传进来的数组,在上级函数中分析并赋值的,表示在该node 上各个zone 大小,zholes_size,表示空洞大小
void __paginginit free_area_init_node(int nid, unsigned long *zones_size,
unsigned long node_start_pfn, unsigned long *zholes_size)
填充pgdat 并调用free_area_init_core