详细讲解MMU—为什么嵌入式Linux没他不行
MMU(Memory Management Unit,内存管理单元)是一种硬件模块,用于在 CPU 和内存之间实现虚拟内存管理。
MMU 内存管理
MMU(Memory Management Unit,内存管理单元)是一种硬件模块,用于在 CPU 和内存之间实现虚拟内存管理。
其主要功能是将虚拟地址转换为物理地址,同时提供访问权限的控制和缓存管理等功能。MMU 是现代计算机操作系统中重要的组成部分,可以提高系统的稳定性和安全性。
在内存管理方面,MMU 可以通过页面表(Page Table)实现虚拟内存管理。页面表是一种数据结构,记录了每个虚拟页面和其对应的物理页面之间的映射关系。
当 CPU 发出一个虚拟地址时,MMU 会通过页面表查找并将其转换为对应的物理地址。
此外,MMU 还可以通过页面表实现内存保护和共享等功能,从而提高系统的安全性和效率。
总之,MMU 是内存管理中一个重要的硬件组件,可以实现虚拟内存管理、内存保护、共享和缓存等功能,为现代计算机操作系统的稳定性和安全性提供支持。
举个例子
假设我们有一个程序,它需要访问两个内存区域:一个是只读的代码区域,一个是可读写的数据区域。
我们现在想要在一个没有 MMU 的系统上运行这个程序。如果没有 MMU,代码区域和数据区域就只能被映射到两个固定的物理地址上。这就意味着,如果程序尝试访问一个不正确的地址,可能会导致系统崩溃。
现在,如果我们在一个具有 MMU 的系统上运行这个程序,情况会有所不同。MMU 可以将程序尝试访问的地址映射到不同的物理地址,这样可以使得代码区域和数据区域在物理内存中不再是固定的位置。
这意味着,如果程序尝试访问不正确的地址,MMU 可以通过重新映射来保护系统不崩溃。
MMU 还可以将多个虚拟地址映射到同一个物理地址上,这就是所谓的页共享(page sharing),可以减少物理内存的使用。
如果没有 MMU,程序访问内存时只能使用物理地址,而物理地址是直接映射到内存芯片上的地址,程序可以随意访问任何一个物理地址。
这种情况下,程序如果访问了错误的地址或试图访问未被授权的地址,就会产生访问错误或非法访问,可能导致系统崩溃、数据丢失等问题。
而有了 MMU,程序访问的是虚拟地址,由 MMU 负责将虚拟地址映射到物理地址上,这样程序就无法直接访问物理地址。
同时,MMU 可以根据内存访问权限来限制程序对内存的访问,确保系统的安全性和稳定性。
因此,没有 MMU 时,程序可能会访问到其他地址,而有了 MMU,程序只能访问被允许访问的地址,可以有效地避免非法访问的问题。
为什么相同的虚拟地址空间在物理地址不会发生冲突呢?
相同的虚拟地址空间在不同的进程中可能会映射到不同的物理地址,这个映射的过程是由 MMU 完成的。在操作系统中,每个进程都有独立的虚拟地址空间,且这些虚拟地址空间互不干扰。
MMU 会将每个进程的虚拟地址映射到对应的物理地址上,使得不同进程间的内存访问不会相互干扰。同时,MMU 也会提供一些安全机制,如页面保护等,来防止进程越界访问内存或访问其他进程的内存。
因此,MMU 起到了保护进程间内存互不干扰的作用,也是现代操作系统的重要组成部分。
页表是什么?
页表是一种用于存储虚拟内存地址与物理内存地址映射关系的数据结构。在使用虚拟内存的系统中,每个进程都有自己的虚拟地址空间,而这些虚拟地址空间被分割成许多页(通常大小为 4KB 或更大),而不是一整块连续的内存。
因此,当进程需要访问某个虚拟地址时,需要将其翻译成对应的物理地址。这个翻译过程就是通过页表来完成的。
页表的基本原理是将虚拟地址划分成一个页号和一个偏移量。
页号用于在页表中查找对应的物理页帧号,而偏移量则用于计算该虚拟地址在物理页帧中的偏移量。通过这种方式,就可以将虚拟地址映射到物理地址,使得进程可以访问对应的内存区域。
页表一般由操作系统来维护,因为操作系统需要掌握虚拟地址和物理地址之间的映射关系。
在使用 MMU(Memory Management Unit)的硬件支持的系统中,当进程访问虚拟地址时,MMU 会通过页表将虚拟地址转换为物理地址,并将访问指向正确的物理地址。这样,进程就可以在不知道自己真实物理地址的情况下访问内存。
为什么没有 MMU 就无法运行 Linux 系统?
这是因为 Linux 内核将虚拟地址空间分为多个页面,并将这些页面映射到物理地址空间上,以实现内存隔离、保护和虚拟内存等功能。
没有 MMU,就无法实现这种映射,从而无法运行 Linux 系统。
为什么有些较为简单的 SOC 可能没有 MMU,但仍然可以运行一些嵌入式操作系统或者裸机程序?
RTOS 可以运行在没有 MMU 的系统上,因为 RTOS 通常不需要进行内存保护和虚拟地址映射等高级特性。
相反,RTOS 的设计侧重于实时性和低延迟,因此通常只需要简单的内存管理和任务调度即可。
这使得 RTOS 可以运行在许多嵌入式系统上,包括一些没有 MMU 的系统。