void __init mem_init(void)
{
unsigned int codepages, datapages, initpages;
int i, node;
codepages = &_etext - &_text;//内核代码段的大小。
datapages = &_end - &__data_start;//内核数据段的大小。
initpages = &__init_end - &__init_begin;//内核初始化相关函数指针空间段的大小。
#ifndef CONFIG_DISCONTIGMEM//如果系统内存空间连续的话。
max_mapnr = virt_to_page(high_memory) - mem_map;//max_mapnr保存着最大低端内存页数。
#endif
if (meminfo.nr_banks != 1)//如果bank不止一个,说明可能存在内存孔洞。
create_memmap_holes(&meminfo);//对每个node的bank进行检查,只要发现前后属于这个node的相邻bank的收尾页号不一
//样的时候,我们就调用free_memmap(),这个函数首先通过页号转换成这两个页对应的
//struct page所在的虚拟地址,然后使这两个虚拟转换成物理地址,并且进行按页对齐,
//最后调用free_bootmem_node()这个函数,使两页之间的页对应的页帧位码表中的相应
//位为0.
for (node = 0; node < numnodes; node++) {//遍历所有节点
pg_data_t *pgdat = NODE_DATA(node);
if (pgdat->node_spanned_pages != 0)
totalram_pages += free_all_bootmem_node(pgdat);//totalram_pages保存释放出低端内存的总页数,我们接下来
//看看free_all_bootmem_node()是如何释放不必要的内存的。
}
unsigned long __init free_