unsigned long __init init_bootmem_node(pg_data_t *pgdat, unsigned long freepfn,
unsigned long startpfn, unsigned long endpfn)
{
return init_bootmem_core(pgdat->bdata, freepfn, startpfn, endpfn);
}
该函数作用:
调用init_bootmem_core函数,初始化pgdat变量中的成员
先看一下pgdat变量的结构
typedef struct bootmem_data {
unsigned long node_min_pfn; /*表示内存起始页帧号*/
unsigned long node_low_pfn; /*表示内存结束页帧号*/
void *node_bootmem_map; /*表示bootmam_map的起始物理地址*/
unsigned long last_end_off; /*表示上一次分配截止地址的偏移。*/
unsigned long hint_idx; /*存放前一次分配的最后一个页面号*/
struct list_head list;
} bootmem_data_t;
static unsigned long __init init_bootmem_core(bootmem_data_t *bdata,
unsigned long mapstart, unsigned long start, unsigned long end)
{
unsigned long mapsize;
mminit_validate_memmodel_limits(&start, &end);//空函数
bdata->node_bootmem_map = phys_to_virt(PFN_PHYS(mapstart));
bdata->node_min_pfn = start;
bdata->node_low_pfn = end;
link_bootmem(bdata);
/*
* Initially all pages are reserved - setup_arch() has to
* register free RAM areas explicitly.
*/
mapsize = bootmap_bytes(end - start);
memset(bdata->node_bootmem_map, 0xff, mapsize);
bdebug("nid=%td start=%lx map=%lx end=%lx mapsize=%lx\n",
bdata - bootmem_node_data, start, mapstart, end, mapsize);
return mapsize;
}
假如调用函数传进来的参数值如下:
mapstart = 0x30431; start = 0x30000; end = 0x31000;
那么:
bdata->node_bootmem_map = phys_to_virt(PFN_PHYS(mapstart));
#define PFN_PHYS(x) ((phys_addr_t)(x) << PAGE_SHIFT)
bdata->node_bootmem_map = phys_to_virt(0x30431000) = 0xc0431000
bdata->node_min_pfn = start = 0x30000
bdata->node_low_pfn = end = 0x31000
mapsize = bootmap_bytes(end - start) = 512
memset(bdata->node_bootmem_map, 0xff, mapsize) 也即
memset(bdata->node_bootmem_map, 0xff, 512)
到这里就可以看出该函数的主要作用:
1,初始化pgdat变量中的主要成员,这些成员在随后即将用到。
2,将用来管理内存状况的那512个字节的数据全部赋值为0xff,也即将4096位全部置1