static unsigned int __init
find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages)
{
unsigned int start_pfn, i, bootmap_pfn;
/*_end 表示内核映像的结束地址(虚拟地址)
__pa(_end) 表示内核映像的结束地址(物理地址)
PAGE_ALIGN(__pa(_end)) 表示页对齐(1page=4K)
*/
start_pfn = PAGE_ALIGN(__pa(_end)) >> PAGE_SHIFT;
bootmap_pfn = 0;
for_each_nodebank(i, mi, node) {
struct membank *bank = &mi->bank[i];
unsigned int start, end;
start = bank_pfn_start(bank); //0x30000
end = bank_pfn_end(bank); //0x31000
if (end < start_pfn)
continue;
if (start < start_pfn)
start = start_pfn;
if (end <= start)
continue;
if (end - start >= bootmap_pages) {
bootmap_pfn = start;
break;
}
}
if (bootmap_pfn == 0)
BUG();
return bootmap_pfn;
}
假如内核映像的结束地址为:_end=0xc04306d0,那么
start_pfn = PAGE_ALIGN(__pa(0xc04306d0)) >> PAGE_SHIFT;
= PAGE_ALIGN(0x304306d0) >> 12
= 0x30431
start_pfn表示的是:从内核映像结束后的页帧号
如果内存的起始地址是0x30000000,大小为0x1000000,那么
start = bank_pfn_start(bank) = 0x30000 //表示内存起始页帧号
end = bank_pfn_end(bank) = 0x31000 //表示内存结束页帧号
最终bootmap_pfn = 0x30431
从0x30000到0x30431之间的页帧号表示的内存存放的大致是内核映像及内核数据,当然也不全是。
像从0x30000000~0x30004000这间存放的是uboot的参数
0x30004000~0x30008000存放的是内存映射表
那么从0x30431之后的页帧号表示的内存就是bootmem需要管理的内存了。