1 bootmem_init分析
文件:arch/arm/mm/mmu.c
paging_init -> bootmem_init
1) 爲pgdat = NODE_DATA(node),pgda->bdata->node_bootmem_map分配內存空間,起始地址爲_end(即kernel的最後地址)。
注:node_bootmem_map佔有的頁框數= [( (memsize)>>12 ) / 8 ]>>12
2) 通過位圖node_bootmem_map先將所有內存頁框標誌爲“0”,然後將node_bootmem_map佔有的內存頁框標誌爲“1”。
reserve_bootmem_node(pgdat,
boot_pfn << PAGE_SHIFT,
boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT);
3) reserve_node_zero(NODE_DATA(node))爲Kernel和pgd保持內存空間,相應位圖標誌爲“1”。
4)bootmem_free_node爲mem_map保持物理頁框(0xC0000000~).
如下圖:
5) memmap_init_zone初始mem_map
bootmem_init->bootmem_free_node->free_area_init_node
->free_area_init_core->memmap_init->memmap_init_zone
for
(pfn = start_pfn; pfn < end_pfn; pfn++) {
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);
mminit_verify_page_links(page,
zone, nid, pfn);
init_page_count(page);
reset_page_mapcount(page);
SetPageReserved(page); //將所有struct
page標誌位PG_Reserved,page_flag.h
...
}
2 alloc_bootmem_low_pages分析
alloc_bootmem_low_pages最終調用alloc_bootmem_core。該函數利用node_bootmem_map查詢所有物理頁框的使用情況:“1”已用,“0”空閒。
-----------------------------
find_block:
sidx = find_next_zero_bit(bdata->node_bootmem_map, midx, sidx);
//發現第一個“0”的位置
sidx =
align_idx(bdata, sidx, step);
eidx = sidx +
PFN_UP(size); //計算需要多少個物理頁框
for (i =
sidx; i < eidx;
i++) //查詢是否連續空閒,否則退出
if
(test_bit(i, bdata->node_bootmem_map)) {
sidx = align_idx(bdata, i, step);
if (sidx == i)
sidx += step;
goto find_block;
}
Author:Woodpecker [email protected]
轉自:http://blog.csdn.net/huyugv_830913/article/details/5886879