返回的即是bitmap的size,下面函数将分配bitmap,
*******************************************************
* memblock_alloc_base这个东东以前没见过,顺着看看
* 在/mm/memblock.c中,这里的参数max_addr为896M
*******************************************************
phys_addr_t __init __memblock_alloc_base(phys_addr_t size, phys_addr_t align, phys_addr_t max_addr)
{
phys_addr_t found;
/* We align the size to limit fragmentation. Without this, a lot of
* small allocs quickly eat up the whole reserve array on sparc
*/
size = memblock_align_up(size, align);
found = memblock_find_base(size, align, 0, max_addr);
if (found != MEMBLOCK_ERROR &&
!memblock_add_region(&memblock.reserved, found, size))
return found;
return 0;
}
*******************************************************
* memblock_find_base在可操作内存范围内,找到第一个bitmap
* size大小的空闲内存
*******************************************************
static phys_addr_t __init_memblock memblock_find_base(phys_addr_t size,
phys_addr_t align, phys_addr_t start, phys_addr_t end)
{
long i;
BUG_ON(0 == size);
/* Pump up max_addr */
if (end == MEMBLOCK_ALLOC_ACCESSIBLE)
end = memblock.current_limit;
/* We do a top-down search, this tends to limit memory
* fragmentation by keeping early boot allocs near the
* top of memory
*/
for (i = memblock.memory.cnt - 1; i >= 0; i--) {
phys_addr_t memblockbase = memblock.memory.regions[i].base;
phys_addr_t memblocksize = memblock.memory.regions[i].size;
phys_addr_t bottom, top, found;
if (memblocksize < size)
continue;
if ((memblockbase + memblocksize) <= start)
break;
bottom = max(memblockbase, start);
top = min(memblockbase + memblocksize, end);
if (bottom >= top)
continue;
found = memblock_find_region(bottom, top, size, align);
if (found != MEMBLOCK_ERROR)
return found;
}
return MEMBLOCK_ERROR;
}
memblock应当是收集的内存信息的一个描述,回头再看一下,这里会找到这么个基地之然后将其
返回,以前这个地址应当是在紧挨着内核镜像bss后面,继续回到arm_bootmem_init
函数,下一个是
/**
* init_bootmem_node - register a node as boot memory
* @pgdat: node to register
* @freepfn: pfn where the bitmap for this node is to be placed
* @startpfn: first pfn on the node
* @endpfn: first pfn after the node
*
* Returns the number of bytes needed to hold the bitmap for this node.
*/
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);
}
/*
* Called once to set up the allocator itself.
* bootmem 核心初始化
*/
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)); //bitmap起始地址
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);
//node_bootmem_map记录bitmap起始地址,清空这里
bdebug("nid=%td start=%lx map=%lx end=%lx mapsize=%lx\n",
bdata - bootmem_node_data, start, mapstart, end, mapsize);
return mapsize;
}
靠,现在的分配器真成分配器了,不带收集的??
总结:总括了bootmem分配器,介绍了其原理,后文准备跟一下memblock这个东东,以及那些分配函数具体实现^.^!.