linux-2.6.14/arch/arm/mm/init.c
static void __init bootmem_init(struct meminfo *mi)
{
struct node_info node_info[MAX_NUMNODES], *np = node_info;
unsigned int bootmap_pages, bootmap_pfn, map_pg;
int node, initrd_node;
bootmap_pages = find_memend_and_nodes(mi, np);
//计算内存页帧位码表所占页数的大小(这里只需用1页)
bootmap_pfn = find_bootmap_pfn(0, mi, bootmap_pages);
//计算存储页帧位码表的物理页号(这里为第 0x303ae 页)
initrd_node = check_initrd(mi);
map_pg = bootmap_pfn;
/*
* Initialise the bootmem nodes.
*
* What we really want to do is:
*
* unmap_all_regions_except_kernel();
* for_each_node_in_reverse_order(node) {
* map_node(node);
* allocate_bootmem_map(node);
* init_bootmem_node(node);
* free_bootmem_node(node);
* }
*
* but this is a 2.5-type change. For now, we just set
* the nodes up in reverse order.
*
* (we could also do with rolling bootmem_init and paging_init
* into one generic "memory_init" type function).
*/
np += num_online_nodes() - 1; // num_online_nodes() = 1
for (node = num_online_nodes() - 1; node >= 0; node--, np--) {
/*
* If there are no pages in this node, ignore it.
* Note that node 0 must always have some pages.
*/
if (np->end == 0 || !node_online(node)) {
if (node == 0)
BUG();
continue;
}
/*
* Initialise the bootmem allocator.
*/
init_bootmem_node(NODE_DATA(node), map_pg, np->start, np->end);
//将页帧位表内的所有页帧位码置为1
free_bootmem_node_bank(node, mi);
//将页帧位表内的所有页帧位码清0
map_pg += np->bootmap_pages;
/*
* If this is node 0, we need to reserve some areas ASAP -
* we may use bootmem on node 0 to setup the other nodes.
*/
if (node == 0)
reserve_node_zero(bootmap_pfn, bootmap_pages);
//将内存中已经使用的物理内存所对应的页帧位置为1
}
#ifdef CONFIG_BLK_DEV_INITRD
if (phys_initrd_size && initrd_node >= 0) {
reserve_bootmem_node(NODE_DATA(initrd_node), phys_initrd_start,
phys_initrd_size);
initrd_start = __phys_to_virt(phys_initrd_start);
initrd_end = initrd_start + phys_initrd_size;
}
#endif
BUG_ON(map_pg != bootmap_pfn + bootmap_pages);
}