linux内核学习(4)建立正式内核的页式内存映射, 以x86 32位模式为例

linux内核学习(4)建立正式内核的页式内存映射, 以x86 32位模式为例

void __init setup_arch(char **cmdline_p)
{
	max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<unsigned long __init_refok init_memory_mapping(unsigned long start, unsigned long end)
	{
		for (i = 0; i < nr_range; i++)
			ret = kernel_physical_mapping_init(mr[i].start, mr[i].end, mr[i].page_size_mask);
			=>unsigned long __init kernel_physical_mapping_init(unsigned long start,
					unsigned long end,
					unsigned long page_size_mask)
			{
				和页表项
				start_pfn = start >> PAGE_SHIFT;
				end_pfn = end >> PAGE_SHIFT;
				pgd_t *pgd_base = swapper_pg_dir;
				pages_2m = pages_4k = 0;
				pfn = start_pfn;
				pgd_idx = pgd_index((pfn<pte_t * __init one_page_table_init(pmd_t *pmd)
						{
							if (!(pmd_val(*pmd) & _PAGE_PRESENT)) {	// 生成页表
								pte_t *page_table = NULL;

								if (after_bootmem) {
						#if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KMEMCHECK)
									page_table = (pte_t *) alloc_bootmem_pages(PAGE_SIZE);
						#endif
									if (!page_table)
										page_table =
										(pte_t *)alloc_bootmem_pages(PAGE_SIZE);
								} else
									page_table = (pte_t *)alloc_low_page();

								paravirt_alloc_pte(&init_mm, __pa(page_table) >> PAGE_SHIFT);
								set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE)); // 将页表物理地址写在页目录项
								BUG_ON(page_table != pte_offset_kernel(pmd, 0));
							}

							return pte_offset_kernel(pmd, 0);
						}

						pte_ofs = pte_index((pfn<

Linux内核源码学习 (1)- 从实模式到保护模式
https://my.oschina.net/u/135465/blog/99590

你可能感兴趣的:(linux内核,内存管理)