根据我的理解,虚拟内存如下:
程序/应用程序/可执行文件驻留在存储设备中。存储设备访问速度比RAM慢得多。因此,程序从存储器存储器复制到主存储器以便执行。由于计算机具有有限的主存储器(RAM),当使用所有RAM时(例如,如果有许多程序同时打开或者如果正在使用一个非常大的程序),启用虚拟内存的计算机将交换数据到硬盘驱动器并根据需要返回内存,因此实际上增加了系统总内存。
据我所知,大多数嵌入式设备没有磁盘存储器(如智能手机或汽车信息娱乐系统)。代码直接从闪存执行。 RAM主要用作暂存区(局部变量,返回地址等)。
那么为什么我们需要在嵌入式系统中使用虚拟内存? (例如WinCE和QNX支持虚拟内存)
答案 0 :(得分:15)
你的理解是完全错误的。您将虚拟内存与交换或页面文件混淆。有些系统具有虚拟内存,没有交换或页面文件,并且有些系统可以在没有虚拟内存的情况下进行交换。
虚拟内存只是意味着进程具有与物理映射不同的内存视图。除此之外,它允许进程拥有自己的虚拟地址空间。
存储设备访问速度比RAM快得多。因此,程序从存储器存储器复制到主存储器以便执行。由于计算机具有有限的主存储器(RAM),当使用所有RAM时(例如,如果有许多程序同时打开或者如果正在使用一个非常大的程序),启用虚拟内存的计算机将交换数据到硬盘驱动器并根据需要返回内存,因此实际上增加了系统总内存。
那是交换(或分页)。除了大多数现代操作系统使用虚拟内存实现交换外,它与虚拟内存无关。交换实际上存在之前虚拟内存。
我认为你可能对这些直接从闪存运行代码的设备不正确。闪存的读取速度非常低,RAM非常便宜。我敢打赌,你提到的大多数系统都没有直接从闪存中运行代码,而是根据需要使用虚拟内存将代码故障转移到RAM中。
答案 1 :(得分:5)
上面有很多答案,David S当然最好的是虚拟内存只是意味着虚拟内存边界一侧的内存地址与该边界另一侧使用的物理地址不同。在哪里,如何,为什么等,边界会有所不同。
虚拟内存的一种常用用法,我可能认为主要用例是操作系统。一个好处是,例如,所有应用程序都可以针对相同的地址空间进行编译,所有应用程序都可以进行编译,从程序的角度来看,它们都从地址0x8000开始,并且当程序运行并访问内存时它会访问基于该地址的东西。硬件和操作系统的组合将程序正在使用的虚拟地址更改为物理地址。如果操作系统允许多任务处理,则每个任务可能认为它们位于相同的地址空间中,但每个任务的物理地址都不同。我不会进一步详细说明为什么使用假定的固定地址空间是一种好处。操作系统使用的另一个方面是内存管理。然而,许多MMU会让你对内存进行分段。如果用户想要分配100兆字节的内存,程序可以在其虚拟地址空间中访问100兆位,就好像它是线性的一样,并且在该地址空间中它是线性的,但是100兆位可能被分解为4Kbyte块,即分散在物理地址空间的所有内容,并不总是可能但技术上肯定可能没有那个物理内存的两个块与100兆的任何其他块相邻。您的内存管理不一定要尝试保留大型物理内存块供应用程序分配。请注意,并非所有MMU都完全相同,而4Kbytes只是一个示例。虚拟地址空间对操作系统的第三个主要好处是保护。如果应用程序绑定到虚拟地址空间,则通常很容易阻止该应用程序触及任何其他应用程序或操作系统的内存。在这种情况下,应用程序将在保护级别操作/执行,使得所有访问都被视为虚拟并且必须经历到物理的转换,用于定义虚拟到物理的表可以包含保护标志。如果应用程序在其虚拟空间中寻址它没有业务访问的内存地址,则硬件可以捕获该内存并让操作系统采取措施来处理它(虚拟化某些硬件,弹出错误并终止应用程序,弹出一个警告而不是杀死应用程序,但同时为他们的交易提供应用程序虚假数据等)。
有很多方法可以在嵌入式系统中使用。首先关闭许多嵌入式系统运行的操作系统,所以以上所有,易于编译程序的地址空间,相对容易的内存管理,以及其他应用程序和操作系统的保护等未提及的好处。 (虚拟化是一个,能够逐块启用/禁用指令/数据缓存是另一个)
尽管大卫S指出了底线。虚拟内存只是意味着虚拟地址不一定等于物理地址,它可以但不一定是,有一些边界,一些硬件,通常是表驱动,将虚拟地址转换为物理地址。您想要这样做的原因有很多,因为某些嵌入式系统与非嵌入式系统无法区分,任何适用于非嵌入式系统的原因都可以应用于嵌入式系统。
尽管人们可能希望您相信系统具有平坦的地址空间,但这通常是一种幻觉。例如,在微控制器中,您可能有多个闪存库和一个或多个RAM组。这些银行中的每一个都具有物理的,通常为零的地址。即使没有mmu或类似的东西,处理器上的地址总线和闪存或RAM存储器上的地址总线之间有一个地方解码处理器上的地址并使用它来寻址特定的存储体。低位通常匹配,高位负责存储区选择(这通常也是mmu的情况),因此从这个意义上说,处理器存在于虚拟地址空间中。 (不限于微控制器,这通常是处理器地址总线的处理方式)对于微控制器,取决于引脚被拉高还是低或某些其他机制,您可能有一个芯片功能,允许一个闪存库用于启动处理器或另一个。您可以将输入引脚拉高,并且引导加载程序中内置的处理器允许您访问和调试系统,例如重新编程应用程序闪存。或者可能将该行拉低并启动应用程序闪存而不是供应商调试器/启动闪存。一些芯片变得更加复杂,让你启动一个闪存,然后程序在某个地方写一个寄存器立即改变内存架构移动的东西,例如允许ram用于中断向量表,这样你的应用程序可以在启动后更改而不是闪存中的矢量表不容易随意改变。
现在,当您谈论虚拟内存时,就交换到磁盘和从磁盘进行交换一样,这是操作系统经常使用的一种技巧,可以产生更多内存的假象。我在虚拟化类别下提到了上述内容。虚拟内存在某种意义上说它不存在,我有X字节但会让软件认为有Y字节(其中Y大于X)可用。操作系统通过硬件使用的虚拟表,管理哪些内存块与物理ram绑定,并允许硬件完成,或者以某种方式标记为不可用,导致操作系统出现异常,检查时,操作系统确定这是此应用程序的有效地址,但此地址后面的数据已交换到磁盘。操作系统然后通过某种算法找到属于任何人(算法的一部分)的另一块ram,并将该块ram复制到磁盘,将与该虚拟相关的表标记为物理无效,然后从中复制所需的块。将磁盘标记为ram,将该块标记为有效,并让硬件完成内存循环 与说vmware或其他虚拟机如何工作没什么不同。您可以使用虚拟内存在硬件上本机执行指令,直到导致异常为止,虚拟机可能认为您具有xyz网络接口并且可能有一个驱动程序正在访问该xyz网络接口中的寄存器,但实际情况你有没有xyz硬件和/或你不希望虚拟机应用程序访问该硬件,所以你虚拟化它,你捕获该注册访问,并使用模拟硬件的软件你伪造访问并让程序在虚拟机器继续。这显然不是执行虚拟机的唯一方法,但是如果硬件支持它,它是一种方式,让虚拟机在硬件上实际运行指令的百分比时间内运行得非常快。虚拟化当然最慢的方法是虚拟化包括处理器在内的所有内容,在这种情况下每个指令都会被模拟,这很慢但有自己的功能(虚拟化臂上的x86或x86上的arm系统,xyz上的abc,填空。)如果这是你在嵌入式系统中讨论的虚拟内存类型,那么如果嵌入式系统在很大程度上与非嵌入式系统(例如xbox或tivo)无法区分,那么出于同样的原因你可以允许这样的事情。如果您使用的是微控制器,那么用例通常意味着如果您需要更多内存,您可以购买更大的微控制器,或者为系统添加更多内存,或者更改应用程序的需求,以便它不需要那么多的内存。可能有例外,但它主要取决于您的应用程序和要求,通用或通用目的,如允许应用程序或其数据大于可用内存的系统,将需要某种解决方案。你的无钥匙进入钥匙链中的微控制器或你的电视遥控器或时钟收音机或通常不需要允许"应用程序"需要比物理上更多的资源。
答案 2 :(得分:2)
使用虚拟内存的更重要的好处是每个进程都有自己的地址空间,与其他进程隔离。这样虚拟内存可以帮助控制故障并提高安全性和稳定性。我应该注意,两个进程仍然可以共享一点内存,以方便通信(共享内存IPC)。
此外,你可以通过将共享部分映射到多个进程(libc浮现在脑海中以供嵌入式使用)地址空间来保存内存,但只能在物理内存中使用一次。这也为它提供了速度提升,你甚至可以通过仅复制内核描述符并将内存映像单独保留直到第一次写入访问完成类似的想法来进一步增强linux的方式fork/clone
。
作为最后一个好处,在现代系统中,通过将文件映射到进程空间来执行文件I / O是很常见的(例如参见mmap
)。
答案 3 :(得分:1)
值得注意的是,人们可以获得“虚拟内存”的一些好处而无需成熟的MMU。硬件要求有时可能非常轻。 PIC 16C505具有5位地址空间和40字节RAM;地址0x10到0x1F可以映射到两组16字节RAM中的任意一个。在编写需要管理两个不同数据流的应用程序时,我安排了所有与一个数据流相关的变量将位于第一组16个“可切换”存储器位置,而与另一个相关联的那些变量将位于相应的第二组中的地址。然后,我可以使用相同的代码来管理两个数据流。只需将银行位设置为一种方式,调用例程,将其设置为另一种方式,然后再次调用例程。
答案 4 :(得分:-2)
虚拟内存存在的原因之一是您的设备可以执行多任务。它也可以充当您的RAM,从而减轻物理RAM的负载并来回交换负载。