博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
物理内存映射
阅读量:4215 次
发布时间:2019-05-26

本文共 3035 字,大约阅读时间需要 10 分钟。

kernel 通过paging_init来映射物理内存void __init paging_init(void){	#为pgd申请内存并赋值,这时候还没有buddy system,因此在早期都是通过memblock来申请内存的	phys_addr_t pgd_phys = early_pgtable_alloc();	pgd_t *pgdp = pgd_set_fixmap(pgd_phys);	#可以看到kernel本身占用的内存是单独映射的,这两个函数我们后面详细分析	map_kernel(pgdp);	map_mem(pgdp);	#在head.s中有申请一段memory来临时映射物理内存swapper_pg_dir,这里我们可以复用	#这段内存,这样我们就可以把通过memblock申请的pgd_phys 释放掉	cpu_replace_ttbr1(__va(pgd_phys));	memcpy(swapper_pg_dir, pgdp, PGD_SIZE);	cpu_replace_ttbr1(lm_alias(swapper_pg_dir));	pgd_clear_fixmap();	#释放pgd_phys 占用的内存	memblock_free(pgd_phys, PAGE_SIZE);	/*	 * We only reuse the PGD from the swapper_pg_dir, not the pud + pmd	 * allocated with it.	 */	 #我们只是复用swapper_pg_dir 中pgd的memory,因此治理释放到pud和pmd 占用的内存	memblock_free(__pa_symbol(swapper_pg_dir) + PAGE_SIZE,		      __pa_symbol(swapper_pg_end) - __pa_symbol(swapper_pg_dir)		      - PAGE_SIZE);}首先看看map_kernelstatic void __init map_kernel(pgd_t *pgdp){	static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_inittext,				vmlinux_initdata, vmlinux_data;	pgprot_t text_prot = rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC;#从下面这段可以看出kernel 本身占用的memory可以分为下面这5段	map_kernel_segment(pgdp, _text, _etext, text_prot, &vmlinux_text, 0,			   VM_NO_GUARD);	map_kernel_segment(pgdp, __start_rodata, __inittext_begin, PAGE_KERNEL,			   &vmlinux_rodata, NO_CONT_MAPPINGS, VM_NO_GUARD);	map_kernel_segment(pgdp, __inittext_begin, __inittext_end, text_prot,			   &vmlinux_inittext, 0, VM_NO_GUARD);	map_kernel_segment(pgdp, __initdata_begin, __initdata_end, PAGE_KERNEL,			   &vmlinux_initdata, 0, VM_NO_GUARD);	map_kernel_segment(pgdp, _data, _end, PAGE_KERNEL, &vmlinux_data, 0, 0);#最终map_kernel_segment->__create_pgd_mapping->pud->pmd->pte等来映射}memblock 中的memory映射如下:static void __init map_mem(pgd_t *pgdp){	phys_addr_t kernel_start = __pa_symbol(_text);	phys_addr_t kernel_end = __pa_symbol(__init_begin);	struct memblock_region *reg;	int flags = 0;	#是否开debug选项	if (debug_pagealloc_enabled())		flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;	/*	 * Take care not to create a writable alias for the	 * read-only text and rodata sections of the kernel image.	 * So temporarily mark them as NOMAP to skip mappings in	 * the following for-loop	 */	#由于kernel 占用的memory页包含在memblock中,且我们再前面已经映射kernel了,所以	#这里标记kernel占用的memory不用在重复映射了	memblock_mark_nomap(kernel_start, kernel_end - kernel_start);#ifdef CONFIG_KEXEC_CORE	if (crashk_res.end)		memblock_mark_nomap(crashk_res.start,				    resource_size(&crashk_res));#endif	/* map all the memory banks */	#开始映射memblock中的memory	for_each_memblock(memory, reg) {		phys_addr_t start = reg->base;		phys_addr_t end = start + reg->size;		#起始地址大于结束地址的话,肯定更有问题,退出		if (start >= end)			break;		#如果memblock包含MEMBLOCK_NOMAP,则不用映射,例如前面提到的kernel的映射		if (memblock_is_nomap(reg))			continue;		#开始映射memblock中的memory		__map_memblock(pgdp, start, end, PAGE_KERNEL, flags);	}		__map_memblock(pgdp, kernel_start, kernel_end,		       PAGE_KERNEL, NO_CONT_MAPPINGS);	#清除kernel memory段的MEMBLOCK_NOMAP	memblock_clear_nomap(kernel_start, kernel_end - kernel_start);}

转载地址:http://knnmi.baihongyu.com/

你可能感兴趣的文章
c,c++宏
查看>>
c++中的枚举类型
查看>>
c++ 运算符重载
查看>>
android使用已安装程序实现分享功能
查看>>
android实现截图功能
查看>>
android 网络连接状态判断与数据类型
查看>>
android webview 实现网页加载进度
查看>>
《人性的弱点》
查看>>
《大师们是如何工作的》
查看>>
c++ 中的多重继承和其权限问题
查看>>
那些年
查看>>
android listview 图文并茂
查看>>
c++中的拷贝构造函数
查看>>
北漂小记—黑客马拉松.北京站
查看>>
《浪潮之巅》1 AT&T
查看>>
《浪潮之巅》2蓝色巨人 IBM公司
查看>>
《浪潮之巅》3水果公司的复兴
查看>>
《浪潮之巅》4计算机工业的生态链
查看>>
《浪潮之巅》5奔腾的芯 英特尔公司
查看>>
《浪潮之巅》7 互联网的金门大桥 -—思科公司
查看>>