5.2.3 着手建立内核永久页表
得到了总的页面数max_pfn和高端页面数highmem_pages之后,来到setup_arch的947行,调用init_memory_mapping()函数来建立系统初始化阶段的临时分页体系,传入的参数意义代表从0~max_low_pfn对应的32位物理地址(低12位全为0,也就是页面对齐),在函数init_memory_mapping函数中先后调用下面的几个函数来设置内存相关数据(因为bootmem此时没有初始化):
find_early_table_space()
kernel_physical_mapping_init()
early_ioremap_page_table_range_init()
load_cr3()
reserve_early()
其中,首先find_early_table_space 所实现的功能是相当重要的:
32static void __init find_early_table_space(unsigned long end, int use_pse, 33 int use_gbpages) 34{ 35 unsigned long puds, pmds, ptes, tables, start; 36 37 puds = (end + PUD_SIZE - 1) >> PUD_SHIFT; 38 tables = roundup(puds * sizeof(pud_t), PAGE_SIZE); 39 40 if (use_gbpages) { 41 unsigned long extra; 42 43 extra = end - ((end>>PUD_SHIFT) << PUD_SHIFT); 44 pmds = (extra + PMD_SIZE - 1) >> PMD_SHIFT; 45 } else 46 pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT; |