- 论坛徽章:
- 0
|
看了下新版本的内核,3.0.8,创建内核最终页表时,会用find_early_table_space()估算一下页目录页表这些需要多少空间,但是它这种估算方法好像是不够的,请高手发表下意见:
不够的原因是映射时是为考虑了mtrr的影响, 最前面的是不按gbpages 或是大页面映射的。
比如说X86_32, PAE关闭,PSE打开,物理地址0~4MB并不是按4MB的大页面映射的,而是一级级的老老实实映射的,见init_memory_mapping()函数。便是计算页目录页表所占的空间时,却是按大页面映射计算的,明显应该是不足的。 唯一能弥补的可能就是PAGE_SIZE对齐时所多出来的点空间,但是也不一定够啊,是算法的问题。。
老版本的内核如何? 还是我哪里理解出问题了?
static void __init find_early_table_space(unsigned long end, int use_pse,
int use_gbpages)
{
unsigned long puds, pmds, ptes, tables, start = 0, good_end = end;
phys_addr_t base;
puds = (end + PUD_SIZE - 1) >> PUD_SHIFT;
tables = roundup(puds * sizeof(pud_t), PAGE_SIZE);
if (use_gbpages) {
unsigned long extra;
extra = end - ((end>>PUD_SHIFT) << PUD_SHIFT);
pmds = (extra + PMD_SIZE - 1) >> PMD_SHIFT; ////不止这个extra需要,0~PUD_SIZE也需要啊,因为0~2/4MB是老老实实一级级映射的。2/4MB~PUD_SIZE必然是大PSE映射,不是GB pages映射的。
} else
pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT;
tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE);
if (use_pse) {
unsigned long extra;
extra = end - ((end>>PMD_SHIFT) << PMD_SHIFT);
#ifdef CONFIG_X86_32
extra += PMD_SIZE;
#endif
ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT;
} else
ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT;
tables += roundup(ptes * sizeof(pte_t), PAGE_SIZE);
#ifdef CONFIG_X86_32
/* for fixmap */
tables += roundup(__end_of_fixed_addresses * sizeof(pte_t), PAGE_SIZE);
#endif
good_end = max_pfn_mapped << PAGE_SHIFT;
base = memblock_find_in_range(start, good_end, tables, PAGE_SIZE);
if (base == MEMBLOCK_ERROR)
panic("Cannot find space for the kernel page tables");
pgt_buf_start = base >> PAGE_SHIFT;
pgt_buf_end = pgt_buf_start;
pgt_buf_top = pgt_buf_start + (tables >> PAGE_SHIFT);
printk(KERN_DEBUG "kernel direct mapping tables up to %lx @ %lx-%lx\n",
end, pgt_buf_start << PAGE_SHIFT, pgt_buf_top << PAGE_SHIFT);
}
复制代码 |
|