linux内存管理 (二) [硬件1] MMU及其运行过程 总览

引言

为什么linux会发展成这个样子,这当然是程序员对程序的要求决定的,
为了满足这些要求,提出了 进程地址空间抽象(1) , 其中 硬件上增加了新的模块MMU(2), 软件上根据MMU的使用手册(3)更新了系统
另外在 进程地址空间抽象 的基础上, 软件上更新了很多新的内存特性(4).


这里主要讲 新的模块MMU(2),且我们这里只看arm的mmu

ARM-MMU文档

科普文档
  • MMU 是 soc 芯片里面的一个硬件单元
  • 去arm官网去搜mmu,得到结果
  • 其中有一个 介绍性文档 : LearnTheArchitecture-MemoryManagement-101811_0100_00_en.pdf
专业文档
  • 去http://infocenter.arm.com搜mmu,得到一个 RF 和 很多TRM(MMU-40x,MMU-500,MMU600,MMU-600AE)
  • arm-mmu 的 RF : IHI0062D_c_system_mmu_architecture_specification.pdf
  • arm-mmu 的TRM : corelink_mmu500_memory_management_unit_r2p4_technical_reference_manual_DDI0517F_en.pdf

MMU 与 内存管理的关系

为了 实现 进程地址空间抽象 , 在 硬件内存管理这方面由MMU负责
硬件内存管理干了什么
	硬件内存管理(MMU)描述了如何控制对 系统内存 的访问。
	每当操作系统或应用程序访问内存时,硬件都会执行内存管理。
	硬件内存管理是一种将内存区域动态分配给应用程序的方法。 // 这个动态分配是什么意思
硬件内存管理的行为导致的效果
	支持虚拟内存系统
	软件只能看到虚拟地址,处理器会将其转换为物理地址。
	这些物理地址被提供给内存系统,并指向内存中的实际物理位置。
// 动态分配???

It is optional which write allocation policies an implementation supports. 
The allocate on write and no allocate on write cache policies indicate which allocation policy is preferred for a memory region, but it should not be relied on that the memory system implements that policy.

实现支持哪些写分配策略是可选的。
写时分配和不写时分配缓存策略指示内存区域首选哪个分配策略,但不应依赖于内存系统实现该策略。

MMU工作流程(三种描述方式)

  • MMU工作流程文字描述
虚拟地址和物理地址的转换 总览
	映射转换(翻译) 的过程
		所需成员:
			cpu mmu mmu中的TLBs mmu中的TableWalkUnit cache 主存中的转换表(页表) 主存中其他部分

		1.取指令,译码
		2.执行load指令(读一个内存地址中的值(value)到r0,内存地址为虚拟地址 va)
			2.1 获取 物理地址 pa
				2.1.1 从 TLBs 中 获取 pa ,如果获取不到则执行2.1.2
				2.1.2 mmu中的TableWalkUnit 从 主存中的转换表(页表) 中获取 pa
			2.2 根据物理地址 pa 获取 value
				2.2.1 从 cache 中获取 value,如果获取不到则执行2.2.2
				2.2.2 从 主存中其他部分 中获取 value.

	
	主内存 中的 转换表 填充了 映射转换 
	映射转换
		虚拟地址通过映射转换为物理地址。
		虚拟地址和物理地址之间的映射存储在转换表(有时称为页表)
	转换表:
		转换表位于内存中,并由软件(通常是OS或管理程序)进行管理。
		转换表不是静态的,并且可以根据软件需求的变化来更新这些表。
		这将更改虚拟地址和物理地址之间的映射。
  • MMU工作流程图解
    在这里插入图片描述

  • MMU工作流程伪代码描述

/*
	level-fetch:
		zhanweifu
		first-level-fetch  // 获取第1级页表项的函数
		second-level-fetch // 获取第2级页表项的函数
		third-level-fetch  // 获取第3级页表项的函数
		fourth-level-fetch // 获取第4级页表项的函数
		zhanweifu2
 */

void walktable(int vma,int *pa){
	level-fetch = zhanweifu;

	do{
		level-fetch = next-level-fetch(level-fetch);
		if (level-fetch == zhanweifu2){
			throw execption;
			return;
		}

		table-item=level-fetch(vma);
		
		is-permission=do-permission-check(current-state,Attributes-of-table-item(table-item));
		if(!is-permission){
			throw execption;
			return;
		}

		is-data-block-index = do-data-block-index-check(Attributes-of-table-item(table-item));

	}while(!is-data-block-index);

	pa = calc-pa(addr-base-of-table-item(table-item),vma);
	return ;
}

int get_value(int pa){
	is_cache_miss = get_value_from_cache(pa,&value);
	if (is_cache_miss){
		get_value_from_ddr(pa,&value);
	}

	return value;
}

int get_pa(int vma){
	is_tlb_miss = tlb(vma,&pa)
	if (is_tlb_miss){
		try {
			walktable(vma,&pa);
		}catch (Exception XXX){
			//TODO
		}
	}
	
	return pa;
}

int mmu(int vma){
	pa = get_pa(vma);
	value = get_value(pa);
	return value;
}

void cpu(void){ // main
	try {
		value = mmu(vma);
	}catch (Exception alignment fault){
		//TODO
	}catch (Exception translation fault){
		//TODO
	}catch (Exception domain fault){
		//TODO
	}catch (Exception permission fault){
		//TODO
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章