MMU和虚拟内存管理

一直觉得runtime真心是个很复杂的东西,一个程序code出来也许不是太困难,但是如果想要了解这个程序在计算机系统上是如何正确运行还真心很不好理解,特别现代的计算机系统和操作系统上大多提供了太多透明的东西,让人更加难以深入理解,只能靠一个问题一个问题好好弄的不迷糊(还不敢说很清楚),否则,只会越来越迷糊,越来越乱。

这里说说虚拟内存管理吧........

学习微机原理时,使用的是DOS,DOS是运行在实模式,不支持多任务,这时内存是地址空间中特定的一块,而且整个地址空间,对于程序员来说,都可以直接操作,当时自己很喜欢这种方式,觉得自己对整个系统都大概很明白,这种感觉很爽,那时做微机原理实验时,大部分都是通过端口来操作adc,dac,8259A等设备,整个系统的连线都可以用画出来,地址线,数据线也可以用示波器来看,而且可以理解得很明白。

但是毕竟技术在发展,那些已经很老了,面对我们的是日渐复杂的计算机系统了,不仅在硬件上,也在操作系统上。对于内存管理来说,计算机系统很多CPU中已经有了MMU(内存管理单元),其实从逻辑角度来看,MMU在计算机中应该和我熟知的中断管理的8259A类似,只是负责的功能不同,有了MMU,必然需要操作系统的支持,就像8259A一样,硬件提供逻辑处理,软件最大化去利用硬件提供的逻辑处理,然后完成一些初始设置,其实类比,他们很像的,我们可以通过思考比较熟悉的8259A来理解MMU和操作系统中的虚拟内存管理。


MMU完成地址转换,将VA转换为PA,这个过程是以页为单位来进行的(32位机器中的页通常是4KB),这是虚拟内存实现的硬件基础,我们知道在X86 CPU中,提供了分段和分页两种机制,分段的硬件基础是CPU内部的段寄存器(实模式下直接有段寄存器来实现,保护模式下还有复杂的GDT,LDT),这些机制给程序员带来很大便利,同时也是高级程序语言的实现成为可能,MMU同样对内存提供了保护机制。

操作系统要做的就是最大化利用MMU提供的功能....

操作系统和MMU是这样配合的:

  1. 操作系统在初始化或分配、释放内存时会执行一些指令在物理内存中填写页表,然后用指令设置MMU,告诉MMU页表在物理内存中的什么位置。

  2. 设置好之后,CPU每次执行访问内存的指令都会自动引发MMU做查表和地址转换操作,地址转换操作由硬件自动完成,不需要用指令控制MMU去做。

这样操作系统可以给每一个一个地址空间为4G(针对32位系统)的虚拟运行环境,我们知道在编译、链接后程序的地址已经都确定了,想想两个运行同一个程序的进程,它们中地址定位信息是相同的,通过MMU的映射可以在不同的物理页上,MMU的存在对多进程,动态链接这些运行时的机制都是有支持的。

对于linux来说,进程的地址空间都是:


虚拟内存管理最主要的作用是让每个进程有独立的地址空间。所谓独立的地址空间是指,不同进程中的同一个VA被MMU映射到不同的PA,并且在某一个进程中访问任何地址都不可能访问到另外一个进程的数据,这样使得任何一个进程由于执行错误指令或恶意代码导致的非法内存访问都不会意外改写其它进程的数据,不会影响其它进程的运行,从而保证整个系统的稳定性。另一方面,每个进程都认为自己独占整个虚拟地址空间,这样链接器和加载器的实现会比较容易,不必考虑各进程的地址范围是否冲突。




你可能感兴趣的:(MMU和虚拟内存管理)