现代操作系统普遍采用虚拟内存管理( Virtual Memory Management) 机制,这需要MMU( Memory Management Unit,内存管理单元) 的支持。
地址转换:MMU将虚拟地址转换为对应的物理地址是以页为单位的,在32为系统中1页为4K。其具体过程如下
- 在操作系统初始化或者分配、释放内存时,会执行一些指令在物理内存中填写页表,然后用指令设置MMU,告诉MMU页表在物理内存中的什么位置。
-
设置好之后, CPU每次执行访问内存的指令都会自动引发MMU做查表和地址转换的操作,地址转换操作完全由硬件完成,不需要用指令控制MMU去做。
内存保护:通常操作系统把虚拟地址空间划分为用户空间和内核空间,例如x86平台的Linux系统虚拟地址空间是0x0000 0000~0xffff ffff,前3GB( 0x0000 0000~0xbfff ffff)是用户空间,后1GB( 0xc000 0000~0xffff ffff)是内核空间。用户程序在用户模式下执行,不能访问内核中的数据,也不能跳转到内核代码中执行。这样可以保护内核,如果一个进程访问了非法地址,顶多这一个进程崩溃,而不会影响到内核和其它进程。 CPU在产生中断或异常时会自动切换模式,由用户模式切换到特权模式,因此跳转到内核代码中执行中断或异常服务程序就被允许了。事实上,所有内核代码的执行都是从中断或异常服务程序开始的,整个内核就是由各种中断处理和异常处理程序组成。我们已经遇到过很多次的段错误是这样产生的:
- 用户程序要访问的一个VA,经MMU检查无权访问。
- MMU产生一个异常, CPU从用户模式切换到特权模式,跳转到内核代码中执行异常服务程序。3. 内核把这个异常解释为段错误,把引发异常的进程终止掉。