这样会遍历所有的bank,start和end分别表示每个bank的开始和结束地址,max_low标记成低端最大值,例如:896M,平时耳熟能详的x86上面,这个值不是个固定值,是根据总内存大小来的,896M比较常见.
**************************************************************
* 回过头来继续看arm_bootmem_init(min, max_low)
* 将刚才得到的值传入,可见bootmem是操作的低端内存
**************************************************************
static void __init arm_bootmem_init(unsigned long start_pfn,
unsigned long end_pfn)
{
struct memblock_region *reg;
unsigned int boot_pages;
phys_addr_t bitmap;
pg_data_t *pgdat;
/*
* Allocate the bootmem bitmap page. This must be in a region
* of memory which has already been mapped.
*
* 分配bitmap所需的内存,bitmap是一个内存单元分配与否的标志,
* 用一个bit来表示,当然它自身也要占用一定内存,参数是低端起始
* 内存到低端上界内存,这里假设拿x86的896M来说,那么就是
* 0---896M,哦,忘了说一点,这里应当是以4k(一页)为单位,
* 所以应当是0---896M/4k
*/
boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
//分配bitmap
bitmap = memblock_alloc_base(boot_pages << PAGE_SHIFT, L1_CACHE_BYTES,
__pfn_to_phys(end_pfn));
/*
* Initialise the bootmem allocator, handing the
* memory banks over to bootmem.
* 初始化分配器核心,包括bitmap内容清空
*/
node_set_online(0);
pgdat = NODE_DATA(0);
init_bootmem_node(pgdat, __phys_to_pfn(bitmap), start_pfn, end_pfn);
/* Free the lowmem regions from memblock into bootmem.
* 把memblock收集的那些内存标志到bootmem中,也就是把这些
* 内存在bootmem中标记成可用在bitmap中
*
*/
for_each_memblock(memory, reg) {
unsigned long start = memblock_region_memory_base_pfn(reg);
unsigned long end = memblock_region_memory_end_pfn(reg);
if (end >= end_pfn)
end = end_pfn;
if (start >= end)
break;
free_bootmem(__pfn_to_phys(start), (end - start) << PAGE_SHIFT);
}
/* Reserve the lowmem memblock reserved regions in bootmem.
* 再过滤一遍,把memblock已用的内存在bitmap中标记成已使用
*
*/
for_each_memblock(reserved, reg) {
unsigned long start = memblock_region_reserved_base_pfn(reg);
unsigned long end = memblock_region_reserved_end_pfn(reg);
if (end >= end_pfn)
end = end_pfn;
if (start >= end)
break;
reserve_bootmem(__pfn_to_phys(start),
(end - start) << PAGE_SHIFT, BOOTMEM_DEFAULT);
}
}
*******************************************************
* bootmem_bootmap_pages是个体系结构无关函数在
* mm/bootmem.c中定义
*******************************************************
/**
* bootmem_bootmap_pages - calculate bitmap size in pages
* @pages: number of pages the bitmap has to represent
*/
unsigned long __init bootmem_bootmap_pages(unsigned long pages)
{
unsigned long bytes = bootmap_bytes(pages);
return PAGE_ALIGN(bytes) >> PAGE_SHIFT;
}
static unsigned long __init bootmap_bytes(unsigned long pages)
{
//页数/8得到需要用多少个字节表示这些页
unsigned long bytes = (pages + 7) / 8;
return ALIGN(bytes, sizeof(long));
}
Linux内存模型之bootmem分配器一(2)
内容版权声明:除非注明,否则皆为本站原创文章。