操作系统的内存管理 -- 分段与分页、虚拟地址、逻辑地址、线性地址、物理地址

2014-01-13 16:08:01   最后更新: 2019-09-03 16:44:33   访问数量:1713




内存管理无疑是操作系统最重要的工作之一,本文我们就来详细介绍一下操作系统是如何管理内存的,分段、分页机制又是什么,线性地址、逻辑地址、物理地址、虚拟地址分别指的又是什么

 

 

由于分页机制是在分段机制的基础上完成的,所以我们首先介绍分段机制

实地址模式中,我们使用段寄存器保存段地址,使用段内变址寄存器保存段偏移地址,这两个组合以后就可以得到物理内存上的物理地址了,但是由于在保护模式中,我们需要对内存加入保护机制,就必须更多的信息,仅仅通过两个寄存器就明显不够了,于是引入了分段机制,在寻址过程中保存更多的保护信息,但是基本的原理还是类似的

 

程序员熟悉和操作的依然是 32 位变址寄存器保存的逻辑地址,但是此时 16 位段寄存器保存的信息已经不仅仅是段基址了

16 位段寄存器中的 0、1 位为 CPL 位,用来标识代码所在段的当前特权级,第2位为 TI 位,用来判断是 GDT(全局描述符表)还是 LDT(局部描述符表),剩下的高 13 位为描述符表项索引

CPU 中有三个48位寄存器:GDTR、IDTR、LDTR,分别保存了内存中 GDT(全局描述符表)、IDT(中断描述符表)和 LDT(局部描述符表)的起始地址和界限(高32位是描述符表起始位置的物理地址,低16位是描述符表界限),一旦通过 16 为段寄存器的最低位确定了描述符表的类型,就可以通过三个寄存器中的一个定位到内存中的描述表,然后通过段寄存器的高 13 位就可以定位到具体的描述符表项

描述符表项中保存有该段的段基址、段界限以及各种保护信息,通过这个段基址,与变址寄存器中保存的 32 位逻辑地址组合就可以得到线性地址了,如果没有通过置位 CPU 中的 CR0 寄存器的最高位而启动分页机制,此时的线性地址就是物理内存的物理地址

 

 

一旦置位了 CPU 中 CR0 寄存器的最高位而启动了分页机制,我们得到的线性地址就需要通过 MMU(内存管理单元)进行分页机制才能转换成物理内存上的物理地址

分段机制存在的必然性和价值体现在描述符中加入的保护位和段界限,让段的使用更加安全,而分页机制其实是在分段机制诞生前诞生的,因为虽然计算机内存在不断增加,但是软件对内存的需求总是无止境的,所以必须要有一个机制,让需求近于无限内存的软件可以在有限的内存环境下使用,于是有了将内存分块,并且将暂时不用的块放到磁盘上的分页机制,同时这个过程对于程序开发人员来说是完全透明的

 

保护模式下的分页机制也和分段机制一样提供了进一步的保护机制

在 32 位系统中,一般使用二级页表,一级页表称为页目录表,页目录表的每个目录项占用 4 字节,共计 1024 个目录项,所以占用 4KB 内存,而每个页面恰好是 4KB,所以整个页目录表占用一个页面,同时,二级页表每个表项也是 4 字节,共计 1024 个表项,所以也占用一个页面,即 4KB 内存,这样,总计可以寻址 1024*1024*4KB = 4GB 内存,恰好是 32 位操作系统的线性地址空间大小

 

页目录表的起始地址存储在 CPU 的 CR3 寄存器上

由分段机制得到的 32 位线性地址被划分为三个部分,高 10 位(22-31)用来寻址页目录表的目录项,通过 CR3 寄存器和线性地址高 10 位,我们就可以得到页表(即二级页表)的起始地址,线性地址的中间 10 位(12-21)用来用来寻址页表的页表项,从而可以在页表中得到物理内存上的页框地址,通过线性地址的低 12 位,就可以确定真正的物理地址了

 

说了这么多,也提到了四个地址:虚拟地址、逻辑地址、线性地址和物理地址,通过和很多人交流讨论、以及在网上查阅很多blog,发现大部分人对这几个地址是很难区分开的,或者存在着很多的误区与不解,下面说说我的理解

 

物理地址

这四个地址中,最容易理解的就是物理地址了,在实地址模式下,程序员操作的就是物理地址,顾名思义,所谓的物理地址就是物理内存上的32位地址,通过物理地址可以直接定位到物理内存上的位置,无论任何操作,最终都必须要得到物理地址才能在物理内存上进行操作

在实地址模式下并没有另外的三个概念,所以要说到另外的三个地址,就不得不说说分段和分页机制,事实上,在上面的描述中,已经讲到了他们的区别

 

虚拟地址

所谓的虚拟地址,从广义上讲,就是相对于物理地址的概念,也就是说,不是物理的就是虚拟的,因为不是物理地址的地址是无法在物理内存上定位的,所以他们都可以被称为“虚拟地址”,也就是说,从这个意义上讲,逻辑地址和线性地址都可以被称为虚拟地址,而从狭义上讲,虚拟地址指的是没有经过分页机制和分段机制转换的地址,也就是段寄存器和变址寄存器内容的组合,从这个意义上来说,虚拟地址就是类似于CS:SI这样形式的地址

 

逻辑地址

逻辑地址就是上层程序员可以操作的地址,也就是变址寄存器中存储的 32 位偏移地址,而其他寄存器上的地址往往对于上层程序员来说是不可更改甚至是不可见的

 

线性地址

对狭义上的虚拟地址通过分段机制以后,可以得到段基址、段界限以及段偏移地址(即逻辑地址),段基址与段偏移地址的组合就是线性地址,线性地址可以在虚拟内存上完成定位,所以也是程序员最关心的地址,线性地址通过 MMU(内存管理单元)利用分页机制进行转换以后就可以得到实际的物理地址了,对于程序员来说,他们并不关注 MMU 如何工作以及其得到的结果,因为了解所操作的内存究竟在哪个页框中是没有什么意义的,所以他们只需要关心线性地址或者逻辑地址就可以完成全部工作了

 

欢迎关注微信公众号,以技术为主,涉及历史、人文等多领域的学习与感悟,每周三到七篇推文,只有全部原创,只有干货没有鸡汤

 

 






技术帖      操作系统      os      现代操作系统      内存管理      虚拟地址      逻辑地址      线性地址      物理地址      分段      分页     


京ICP备15018585号