在对free_area_init_node()函数分析之前,我们也要看看它的源头,这个函数的调用过程如下start_kernel()->paging_init()->free_area_init_node(),我们来看看在调用这个函数之前,在paging_init()前面的语句做了些什么。
/*
* initialise the zones within each node
*/
for (node = 0; node < numnodes; node++) {
unsigned long zone_size[MAX_NR_ZONES];//存放这个内存node的全部内存页数。
unsigned long zhole_size[MAX_NR_ZONES];//存放这次内存node的孔洞内存页数。(每个成员对应该内存node的一个页区)
struct bootmem_data *bdata;
pg_data_t *pgdat;
int i;
/*
* Initialise the zone size information.
*/
for (i = 0; i < MAX_NR_ZONES; i++) {
zone_size[i] = 0;
zhole_size[i] = 0;
}//对这次内存node的最多3个内存页区内存页数和孔洞内存页数清零。
pgdat = NODE_DATA(node);//获得这个node对应的disconting_node_data[n]
bdata = pgdat->bdata;
/*
* The size of this node has already been determined.
* If we need to do anything fancy with the allocation
* of this memory to the zones, now is the time to do
* it.
*/
zone_size[0] = bdata->node_low_pfn -
(bdata->node_boot_start >> PAGE_SHIFT);//获得本次内存node的全部页数
/*
* If this zone has zero size, skip it.
*/
if (!zone_size[0])
continue;
/*
* For each bank in this node, calculate the size of the
* holes. holes = node_size - sum(bank_sizes_in_node)
*/
zhole_size[0] = zone_size[0];
for (i = 0; i < mi->nr_banks; i++) {
if (mi->bank[i].node != node)
continue;
zhole_size[0] -= mi->bank[i].size >> PAGE_SHIFT;
}//上面这个循环可以很容易弄明白zhole_size[0]存放着本次内存node的内存孔洞的页数。
/*
* Adjust the sizes according to any special
* requirements for this machine type.
*/
arch_adjust_zones(node, zone_size, zhole_size);//这是一个空函数。
free_area_init_node(node, pgdat, zone_size,
bdata->node_boot_start >> PAGE_SHIFT, zhole_size);
}
void __init free_area_init_node(int nid, struct pglist_data *pgdat,
unsigned long *zones_s