- 論壇徽章:
- 0
|
看了下新版本的內(nèi)核,3.0.8,創(chuàng)建內(nèi)核最終頁(yè)表時(shí),會(huì)用find_early_table_space()估算一下頁(yè)目錄頁(yè)表這些需要多少空間,但是它這種估算方法好像是不夠的,請(qǐng)高手發(fā)表下意見:
不夠的原因是映射時(shí)是為考慮了mtrr的影響, 最前面的是不按gbpages 或是大頁(yè)面映射的。
比如說(shuō)X86_32, PAE關(guān)閉,PSE打開,物理地址0~4MB并不是按4MB的大頁(yè)面映射的,而是一級(jí)級(jí)的老老實(shí)實(shí)映射的,見init_memory_mapping()函數(shù)。便是計(jì)算頁(yè)目錄頁(yè)表所占的空間時(shí),卻是按大頁(yè)面映射計(jì)算的,明顯應(yīng)該是不足的。 唯一能彌補(bǔ)的可能就是PAGE_SIZE對(duì)齊時(shí)所多出來(lái)的點(diǎn)空間,但是也不一定夠啊,是算法的問(wèn)題。。
老版本的內(nèi)核如何? 還是我哪里理解出問(wèn)題了?
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; ////不止這個(gè)extra需要,0~PUD_SIZE也需要啊,因?yàn)?~2/4MB是老老實(shí)實(shí)一級(jí)級(jí)映射的。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);
}
復(fù)制代碼 |
|