unsigned long __init bootmem_bootmap_pages(unsigned long pages)
{
unsigned long bytes = bootmap_bytes(pages);
return PAGE_ALIGN(bytes) >> PAGE_SHIFT;
}
该函数由bootmem_init_node函数调用,传进来的参数值为(end_pfn - start_pfn)
假如end_pfn = 0x31000 start_pfn=0x30000 那么pages = 0x1000
然后调用bootmap_bytes函数
该函数中"bytes = (pages + 7) / 8"的作用:
计算pages个页需要多少个字节来描述(每1位描述1页[page])
加7除以8 和 不加7除以8 的区别:
假如有16个页,那么需要2个字节来描述(2 * 8)
(16 + 7) / 8 = 2; (16 ) / 8 = 2;
假如有17个页,那么需要3个字节来描述(3 * 8),虽然还有7位没有用,但必须得分配3个字节
(17 + 7) / 8 = 3; (17 ) / 8 = 2;
static unsigned long __init bootmap_bytes(unsigned long pages)
{
unsigned long bytes = (pages + 7) / 8;
return ALIGN(bytes, sizeof(long));
}
那么根据上面的值,可以得出该函数最后返回的值为:
bytes = (0x1000 + 7) / 8 = 512
ALIGN(512, sizeof(long)) = 512
再返回到bootmem_bootmap_pages函数中,最终返回值为:
PAGE_ALIGN(512) >> PAGE_SHIFT = 4096 >> 12 = 1
bootmem_bootmap_pages函数的作用
1,计算需要多少个字节来描述pages
众所周知,bootmap的原理就是用1位[bit]来描述1页[page],多少个page就需要多少位[bit],然后再换算成多少字节[bytes]
2,根据上面计算的字节数再来计算:需要多少页才能够分配这么多字节。
因为1页有4K[4096]个字节,所以要分配512个字节只需要1页就够了。