这个宏用于初始化mem_map中每个page的数据。#define memmap_init(size, nid, zone, start_pfn) /memmap_init_zone((size), (nid), (zone), (start_pfn), MEMMAP_EARLY)/** Initially all pages are reserved - free ones are freed* up by free_all_bootmem() once the early boot process is* done. Non-atomic initialization, single-pass.*/void __meminit memmap_init_zone(unsignedlong size, int nid, unsignedlong zone,unsignedlong start_pfn, enum memmap_context context){struct page *page;unsignedlong end_pfn = start_pfn + size;unsignedlong pfn;for (pfn = start_pfn; pfn < end_pfn; pfn++) {/** There can be holes in boot-time mem_map[]s* handed to this function.They do not* exist on hotplugged memory.*/if (context == MEMMAP_EARLY) {if (!early_pfn_valid(pfn))continue;if (!early_pfn_in_nid(pfn, nid))continue;}page = pfn_to_page(pfn);set_page_links(page, zone, nid, pfn);init_page_count(page);reset_page_mapcount(page);SetPageReserved(page);INIT_LIST_HEAD(&page->lru);}}调用此函数时size为整个SDRAM区域的页数,对于64M内存(限制为60M),其值为0x3bff。其余几个参数均为0。从这个函数可以看出,它依次对每个页的描述符page均进行了初始化。pfn_to_page的定义如下:#define pfn_to_page(pfn)virt_to_page(pfn_to_virt(pfn))#define pfn_to_virt(pfn)__va((pfn) << PAGE_SHIFT)#define __va(paddr)phys_to_virt((unsignedlong)(paddr))#define phys_to_virt(vaddr)((void *) (vaddr))#define virt_to_page(addr)(mem_map + (((unsignedlong)(addr)-PAGE_OFFSET) >> PAGE_SHIFT))其实就是根据一个内存地址找到它所在页的描述结构page。/** Setup the page count before being freed into the page allocator for* the first time (boot or memory hotplug)*/staticinlinevoid init_page_count(struct page *page){atomic_set(&page->_count, 1);}将_count成员初始化为1。/** The atomic page->_mapcount, like _count, starts from -1:* so that transitions both from it and to it can be tracked,* using atomic_inc_and_test and atomic_add_negative(-1).*/staticinlinevoid reset_page_mapcount(struct page *page){atomic_set(&(page)->_mapcount, -1);}比较简单,将_mapcount值设置为1。#define SetPageReserved(page)set_bit(PG_reserved, &(page)->flags)从这里可以看出,初始化后的flags成员将带有唯一的标记PG_reserved。