Chinaunix首页 | 论坛 | 博客
  • 博客访问: 177460
  • 博文数量: 30
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 440
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-23 19:45
文章分类

全部博文(30)

文章存档

2016年(2)

2010年(3)

2009年(8)

2008年(17)

我的朋友

分类:

2008-09-13 10:47:33

在计算机中各种地址让人眼花缭乱,这些地址的存在都是为了让CPU能准确的访问到存储器中的数据单元,那么CPU如何通过地址访问到存储单元的了?先来看一个图:

从此图可以看到CPU首先将虚拟地址送到MMU(内存管理单元),然后经MMU将虚拟地址转换成物理地址,最后就可以通过总线去访问到存储单元。在这个过程中MMU起到了举足轻重的作用,它将虚拟地址转换成了物理地址,接下来再看下图,看看MMU如何工作的。

在这个过程中,MMU首先将虚拟地址通过分段机制转换成线性地址,然后再通过分页机制将线性地址转换成物理地址,其中的每一步都有它的道理和设计的巧妙之处。此过程涉及到了三种不同的地址,即虚拟地址,线性地址,物理地址,和两种不同的机制:分段机制和分页机制。接下来就依次说说我对这些东东的理解。

       首先何为虚拟地址?我们都知道程序都运行在虚拟空间,在这上面的地址就是虚拟地址,此地址并非真正的物理地址,比如说你写的一条指令:printf();,当此指令对应一个虚拟的地址,当运行时才将此地址通过MMU映射到内存,即找到物理地址。一般用

“段:偏移量”来表示。线性地址是指一段连续的、不分段的、范围0~4GB的地址空间,一个线性地址就是线性地址空间的一个绝对地址。物理地址,这个就是真正硬件上的地址,每个物理地址对应一个内存存储单元。

那么现在再来看看分段机制如何实现,如何将虚拟地址转换成线性地址。在此我们先看看虚拟地址的结构:

其中选择子(selector)就是我们经常所说的CSDSES FS SS GS等。这些16位的选择子又分为三部分:索引部分、TI部分和RPL(当前特权级)部分。其中RPL03)决定当前进程访问相应段的权限;TI(为01),以此来决定当前进程是选择GDT(全局描述附表),还是LDT(局部描述符表);然后再由索引部分决定深入到GDTLDT的偏移。GDT(LDT)相当于一个数组,存在于内存中,每个元素是一个8个字节的描述符,每个描述符都描述一个相应的段(如系统代码段、用户数据段、堆栈段)。由一个选择子惟一选择一个描述符,然后通过这个描述符来描述描述了一个特定的段(如用户代码段)的段基地址,段的最大偏移,段的所有存取权限等(“描述符”的名字由此而来)。32位偏移部分就是对这个段的偏移。这样就由这个虚拟地址惟一地确定了一个32位的线性地址。看下面的图帮助理解:

其中的GDTR为系统寄存器,存放着GDT的基地址(物理地址),同样有个LDTR系统寄存器,正是由于他们我们才能找到内存中的GDT。当TI=0时选择GDTTI=1时为LDT

段机制将虚拟地址转换成了线性地址,下面就交给了分页机制,通过分页机制才最终将其转换成了物理地址。

每一个线性地址被分成3个部分(相对于两级分页机制来说),其中前两部分各占10位分别用来作为也目录和页表的索引,最后一个部分占12位,最为一个页帧的索引。页目录、页表都存在于内存中,由系统寄存器CR3保存页目录的基地址。转换过程图如下:

先通过页面索引找到页目录项,然后再从页目录项中找到与其对应的页表(存储物理页地址的一个表),再由页表索引找到页表项(即物理页地址),最后通过页里偏移找到真正的物理地址。到这里就完成了上述地址间的转换。

 

阅读(1401) | 评论(1) | 转发(0) |
0

上一篇:系统调用过程

下一篇:完成量使用实例

给主人留下些什么吧!~~

niutao.linux2008-09-15 19:49:34

很详细了!fighting!