处理器中的MMU(内存管理单元)单元如何保护内存段

Ren*_*h G 5 architecture embedded

在通过一个嵌入式处理器架构时,我已经看到了块MMU,它主要提到了内存保护功能.

我可否知道 ,

MMU如何提供这种保护以及为什么需要它?什么是记忆保护的意思?

除了保护(如虚拟寻址)之外,MMU的其他用途是什么?

请考虑没有操作系统的嵌入式系统.

__Kanu

old*_*mer 19

对于使用内存(大多数)的处理器,有一种类型的内存接口,有些具有名称(如amba,axi,wishbone),有些则没有.从处理器的角度来看,这是地址和数据,请您读取或写入该地址的内容.在过去的好日子里,您将拥有一条总线,您的闪存和内存和外围设备将位于此总线上,查看地址的某些(通常是高位)位以确定它们是否正在被寻址,如果是,则从中读取或跳转否则,数据总线仍处于三态.今天取决于芯片等,一些内存解码发生在核心或靠近核心,你的核心或芯片的公共接口可能是几个总线,可能有一个特定的闪存总线,一个特定的sram总线和特定的dram公共汽车等

因此,对于扁平线性地址空间的第一个问题,即使划分为闪存和ram,ram部分也是平坦的,对于N个字节,地址0到N-1.对于非嵌入式操作系统,如果只有一些方法让程序假设它们都是从地址0或地址0x100或地址0x8000开始,那么让人们的生活更轻松,而不必为了下一个空闲内存而以某种方式编译空间是,或者操作系统不必完全从低级内存中移出程序,并在任务切换时将其替换为另一个程序.一个简单易懂的方法是使用intels段:偏移方案.程序总是在同一个地方开始,因为在启动程序之前调整了代码段,并且使用了偏移量来执行(非常简化的模型视图),当程序之间的任务切换只需更改代码段时,请为下一个程序恢复pc.一个程序可能位于地址0x1100,另一个程序位于0x8100,但两个程序都认为它们位于地址0x0100.所有开发人员都很容易.MMU通过在处理器总线上获取该地址并将其称为虚拟地址来提供相同的功能,mmu通常靠近处理器存储器接口和芯片/世界其余部分之间的处理器.所以你可以再次让mmu看到地址0x0100在表中查找并转到物理地址0x0100,然后在任务切换时更改表,以便下一次取0x0100转到0x1100.每个程序都认为它在地址0x0100处运行,链接,编译,开发,加载和执行代码不那么痛苦.恢复下一个程序的电脑.一个程序可能位于地址0x1100,另一个程序位于0x8100,但两个程序都认为它们位于地址0x0100.所有开发人员都很容易.MMU通过在处理器总线上获取该地址并将其称为虚拟地址来提供相同的功能,mmu通常靠近处理器存储器接口和芯片/世界其余部分之间的处理器.所以你可以再次让mmu看到地址0x0100在表中查找并转到物理地址0x0100,然后在任务切换时更改表,以便下一次取0x0100转到0x1100.每个程序都认为它在地址0x0100处运行,链接,编译,开发,加载和执行代码不那么痛苦.恢复下一个程序的电脑.一个程序可能位于地址0x1100,另一个程序位于0x8100,但两个程序都认为它们位于地址0x0100.所有开发人员都很容易.MMU通过在处理器总线上获取该地址并将其称为虚拟地址来提供相同的功能,mmu通常靠近处理器存储器接口和芯片/世界其余部分之间的处理器.所以你可以再次让mmu看到地址0x0100在表中查找并转到物理地址0x0100,然后在任务切换时更改表,以便下一次取0x0100转到0x1100.每个程序都认为它在地址0x0100处运行,链接,编译,开发,加载和执行代码不那么痛苦.一个程序可能位于地址0x1100,另一个程序位于0x8100,但两个程序都认为它们位于地址0x0100.所有开发人员都很容易.MMU通过在处理器总线上获取该地址并将其称为虚拟地址来提供相同的功能,mmu通常靠近处理器存储器接口和芯片/世界其余部分之间的处理器.所以你可以再次让mmu看到地址0x0100在表中查找并转到物理地址0x0100,然后在任务切换时更改表,以便下一次取0x0100转到0x1100.每个程序都认为它在地址0x0100处运行,链接,编译,开发,加载和执行代码不那么痛苦.一个程序可能位于地址0x1100,另一个程序位于0x8100,但两个程序都认为它们位于地址0x0100.所有开发人员都很容易.MMU通过在处理器总线上获取该地址并将其称为虚拟地址来提供相同的功能,mmu通常靠近处理器存储器接口和芯片/世界其余部分之间的处理器.所以你可以再次让mmu看到地址0x0100在表中查找并转到物理地址0x0100,然后在任务切换时更改表,以便下一次取0x0100转到0x1100.每个程序都认为它在地址0x0100处运行,链接,编译,开发,加载和执行代码不那么痛苦.MMU通过在处理器总线上获取该地址并将其称为虚拟地址来提供相同的功能,mmu通常靠近处理器存储器接口和芯片/世界其余部分之间的处理器.所以你可以再次让mmu看到地址0x0100在表中查找并转到物理地址0x0100,然后在任务切换时更改表,以便下一次取0x0100转到0x1100.每个程序都认为它在地址0x0100处运行,链接,编译,开发,加载和执行代码不那么痛苦.MMU通过在处理器总线上获取该地址并将其称为虚拟地址来提供相同的功能,mmu通常靠近处理器存储器接口和芯片/世界其余部分之间的处理器.所以你可以再次让mmu看到地址0x0100在表中查找并转到物理地址0x0100,然后在任务切换时更改表,以便下一次取0x0100转到0x1100.每个程序都认为它在地址0x0100处运行,链接,编译,开发,加载和执行代码不那么痛苦.然后当你进行任务切换时,你改变了表,所以0x0100的下一次提取变为0x1100.每个程序都认为它在地址0x0100处运行,链接,编译,开发,加载和执行代码不那么痛苦.然后当你进行任务切换时,你改变了表,所以0x0100的下一次提取变为0x1100.每个程序都认为它在地址0x0100处运行,链接,编译,开发,加载和执行代码不那么痛苦.

下一个功能是缓存,内存保护等.因此,处理器及其内存控制器可能会在到达mmu之前解码某些地址,可能是某些核心寄存器,也许是mmu控件本身.但是其他的东西,如内存和外围设备,可以在mmu的另一侧,在缓存的另一侧,通常是mmu之外的洋葱的下一层.例如,当轮询串行端口以查看是否有另一个字节可用时,您不希望缓存数据访问,以便首次读取串行端口状态寄存器实际上在物理总线上读取并触及串行端口,然后全部后续读取读取缓存中的陈旧版本.你确实想要这个ram值,缓存的目的,但对于像状态寄存器这样的易失性事物,这是非常糟糕的.因此,根据您的系统,在启用mmu之前,您可能无法打开数据缓存.例如,ARM上的存储器接口具有控制位,用于指示它是什么类型的访问,是不可缓存的访问,可缓存的,突发的一部分,等等.因此,您可以启用独立于数据缓存的指令缓存,并且如果没有mmu,它将直接将这些控制信号传递到缓存控制器,然后缓存控制器连接到外部世界(如果它没有处理事务).因此,您的指令获取可以缓存其他未缓存的内容.但是要缓存数据ram访问而不是串行端口的状态寄存器,你需要做的是为mmu设置表格,在嵌入式环境中你可以选择简单地将ram一对一映射,意味着地址0x1000虚拟变为0x1000物理,但您现在可以为该块内存启用数据缓存位.然后,对于串行端口,您可以将虚拟地址映射到物理地址,但是清除该块内存空间的数据高速缓存启用位.现在你可以启用数据缓存,现在缓存内存读取(因为当它们通过mmu时的控制信号被标记为这样,但是对于你的寄存器访问,控制信号指示不可缓存).

您当然不必将虚拟映射到物理一对一,取决于嵌入式或非嵌入式,操作系统与否等等.但这是您的保护所在.在操作系统中最容易看到.应该不允许应用程序层的应用程序获取受保护的系统内存,内核等.应该无法破坏其他应用程序的内存空间.因此,当切换应用程序时,mmu表会反映允许访问的内存以及不允许访问的内存.程序不允许的任何地址都被mmu捕获,生成异常/故障(中断)并且内核/主管获得控制权并且可以处理该程序.您可能还记得早期窗口日期中的"一般保护错误"一词,在市场营销和公司的其他利益集团决定我们应该更改名称之前,它直接来自英特尔手册,当你有一个不属于其他类别的错误时,就会触发该中断,例如测试A上的多项选择题bob,B ted,C alice,D以上都不是.一般的保护错误不是上面的一个categetory,但是受欢迎程度最高,因为这是当你的程序试图在其分配的内存空间之外访问内存或i/o时所得到的.

mmus的另一个好处是malloc.在mmus之前,内存分配必须使用方案来重新安排内存以在中间保留大的空块.对于那个下一个大型malloc,最小化"4meg free为什么我的1kbyte alloc失败?".现在,就像磁盘一样,你将内存空间分成这些4kbyte或一些这样大小的块.大小为一块或更小的malloc,在内存中取任何空闲块使用mmu表条目指向它并向调用者提供与该mmu条目绑定的虚拟地址.你想要4096*10字节,诀窍不是要找到那么多线性内存,而是找到10个线性mmu表条目,取任意10块内存(不一定是相邻的)并将它们的物理地址放在10 mmu条目中.

最重要的是,它是如何做到的,它通常位于处理器和缓存之间,或者如果没有缓存物理内存总线.mmu逻辑查看地址,使用它来查看表.表中的位包括物理地址加上一些包含可缓存的控制信号,以及指示这是有效条目还是受保护区域的某种方式.如果该地址受到保护,则mmu会将中断/事件激发回核心.如果有效,它会修改虚拟地址,使其成为mmu另一端/外部的物理地址,而像可缓存位这样的位用于告诉mmu另一端的任何类型的事务,指令,数据,可缓存,突发等.对于嵌入式,非操作系统,单任务系统,您可能只需要一个mmu表.


RBe*_*eig 9

MMU(内存管理单元)是希望拥有独立和受保护的内存空间的基本系统块.我将保持这个简单,因为整本书可以写关于内存管理硬件和策略......

没有保护,在任何进程中运行的程序都可以访问任何其他进程的内存.即使您忽略了安全隐患,这也意味着一个程序中的错误可能会覆盖属于某个其他进程的内存.调试这类问题并不容易,因为症状显示距离原因很远.

因此,需要某种组织原则,以便每个进程只能查看和修改分配给它的内存.并且,由于错误发生,重要的是该组织由硬件支持,以便即使意外访问错误的内存部分也很困难.

这样做的一个优点是,还可以使每个进程的存储器映射看起来相同.链接器可以将每个程序定位在相同的起始地址,将堆栈和堆放入可预测的区域,并保留内存以与内核进行交互.

MMU是实现从进程使用的逻辑地址到硬件使用的物理地址的转换的硬件组件.它还提供安全功能,例如仅将某些内存部分标记为可执行文件.它提供了内核实现进程交换和虚拟内存所需的数据结构,因此进程B甚至无法看到属于进程A的内存页,但可信内核可以看到A和B.

为了以实用的方式实现这一点,物理存储器被分成页面,通常大小为4KB.每个逻辑地址都分为页码和偏移量.页码索引MMU中的表,该表将每个逻辑页面转换为某个物理地址.此转换发生在每个内存访问周期中.单个物理页面可以映射到无进程(在这种情况下可能也在一个空闲页面池中),只有一个或几个.

进程的堆栈,数据和堆通常由映射到该进程的页面组成.这有助于防止一个进程中的错误影响其他进程,因为每个进程只能写入自己的堆栈,数据和堆页面.

如果将同一页物理内存映射到多个进程,则这些进程可见.这就是Windows上的DLL或Unix上的.so的共享方式:保存程序文本的页面被映射到链接到它的每个进程.

MMU有一种机制,在访问尚未映射到进程的页面时抛出异常.处理该异常可以实现虚拟内存,并在需求发生变化时增加分配给进程的内存量.

  • @Renjith G:如果没有操作系统,通常会将MMU配置为单个地址空间,通常使用直接物理=虚拟映射.您可以将代码空间配置为只读,以防止意外或恶意修改.但是,没有操作系统或RTOS意味着单线程/进程操作,因此保护一个线程或处理数据空间的能力不是问题. (3认同)