一、存储器的管理

      存储器的管理是一种硬件机制,微处理器在总线地址上对物理存储器进行寻址。但是,为了给程序提供比物理存储器容量更大的空间,就引入了虚拟存储器的概念,它在外存(比如磁盘)的支持来下实现,通常所说的虚拟地址称为逻辑地址。对80386来说,既有段的管理又有页的管理。对段和页的管理属于操作系统的职责,80386从硬件上提供管理机制。

二、Intel 80386 微处理器的三种工作方式

      三种工作方式:实地址方式,虚地址保护方式,虚拟8086方式。

      1. 实地址方式

      80386在硬件复位后处于该模式下,只能使用32位地址总线的低20位地址,寻址空间为1MB。此时他就是一个8086/8088微处理器,不同的是它不仅可以运行8086/8088的全部指令,还可以运行32位的运算类指令。系统初始化区在FFFFFFF0H-FFFFFFFFH存储区内。设置此方式是为了与8086兼容,也可从实地址方式转变到保护虚地址方式。物理地址由8386芯片地址引线送出的低的20位地址码,经过存储器译码后选择一个存储单元进行读写,物理地址可用5位的十六进制来表示20位的地址。储器地址分段是把1MB
的存储器空间分成若干段,每段的容量最大为64KB,每个段首地址的高16位二进制代码就是该段的段号(称段基地址)。存储器采用分段管理后,段地址存放在段寄存器CS、DS、SS、ES中,对段寄存器设置不同的值来使微处理器的段寄存器指向存储器中不同的段。偏移地址是相对于某段首地址的段内偏移量。物理地址的形成,把段地址左移4 位得到段基地址,再加上偏移地址值就形成了20 位的物理地址。计算表示方式如下:

段地址×10H+偏移地址=物理地址

80386在实地址方式下的地址转换如图一:

2.虚地址保护方式

当Intel 80386/486 的控制寄存器CR0 的最低位为PE(Protection Enable)保护模式允许位,用来启动CPU进入虚地址保护方式。PE=0表示CPU工作在实地址方式,PE=1表示CPU工作在虚地址保护方式。

80386/486的存储器管理机制采用了分段和分页管理。分段机制是先把逻辑地址转换成线性地址,然后用分页机制把线性地址转换为物理地址。逻辑地址都由一个段地址和偏移量组成,是在程序中对存储器地址的一种表示方法,逻辑地址 = 段地址:偏移地址。当分页机制被禁止使用时,线性地址就成了物理地址了。

(1)段选择符和段寄存器

段寄存器用来存放段选择符,段寄存器有CS、DS、SS、ES、FS、GS,段选择符是16位,而偏移量位一个32位长的字段。段选择符是由16 位组成的,这16 位又被进一步分成3个部分:分别是13 位索引字段、1 位的指示符字段TI 以及2 位的请求特权级字段RPL。索引指端指定了放在GDT或LDT中相应的段描述符的入口。TI标志知名段描述符是在GDT(TI=0)还是在LDT(TI=1)中。RPL表示当前的段选择符装入到CS寄存器时指示出CPU当前的特权级。段选择符如图二:

图二 段选择符

(2)段描述符

每个段由一个64位(8字节)的段描述符来表示,它描述了段的特征。段描述符存放在全局描述符表(GDT)或局部描述符表(LDT)中。由于每个段描述符为8个字节,所以段描述符在GDT或LDT内的相对地址为段选择符的最高13位的值乘以8。段描述符的一般格式如图三:

段描述符中各个字段和标志的含义如下:

      1)基地址字段Base(Base address field):包含段的首字节的线性地址。

      2)段限长字段Limit(Segment limit field):用于指定段的长度。如果G=0,则段长度Limit范围可从1字节到1MB之间,单位为字节;如果G=1,则段长度Limit范围可从4KB~4GB,单位为4KB。

      3)粒度标志G:如果该位为0,则段的单位为字节;如果位为1,则段的单位为4KB。可以结合段限长字段Limit来理解。

      4)段类型字段TYPE(Type field):描述了段的类型特征和它的存取权限。该字段的解释依赖于描述符类型标志S,由S来解释是一个代码或数据段描述符,还是一个系统描述符。TYPE字段的编码对代码、数据或系统描述符都不同,如图四。

5)描述符类型标志S(Descriptor type flag):如果S=0,则一个段描述符是系统段描述符,比如存放LDT这种关键的数据结构;如果S=1,则存放代码或数据段描述符。

      6)描述符特权级字段DPL(Descriptor privilege level):描述符的特权级,用于控制对段的访问,表示CPU访问这个段需要的最小的优先级。特权级范围从0到3。0级特权级最高,3级最低。

      7)段存在标志P(Segment present):用于指出一个段是在内存中(P=1)还是不在内存中(P=0)。对于Linux是来说总是把这个标志设为1,以为它从来不把整个段交换到磁盘上去。

      8)D/B(默认操作大小/默认栈指针大小和/或上界限)标志(Default operation size/default stack pointer size and/or upper bound):根据段描述符描述的是一个可执行代码段、下扩数据段还是一个堆栈段。这个标志具有不同的功能,对于32位代码和数据段,这个标志应该总是设置为1;对于16位代码和数据段,这个标志被设置为0。

      9)可用和保留位(Available and reserved bits):由操作系统使用,但是linux忽略该字段。

(3)段描述表及段描述表寄存器

      80386/486 微处理器有全局描述符表寄存器GDTR、局部描述符表寄存器LDTR 和中断描述符表寄存器IDTR,通过它们分别来查找全局描述符表GDT、局部描述符表LDT 和中断描述符表IDT。

(4)分段和分页机制

分段单元把逻辑地址转换成线性地址。由于段选择符的高14位(13位索引号和1位TI位)是用来进行段描述符选择的,因此虚拟存储器中的段数最大可到16K(2的14次方)个;由于偏移量位长度为32位,那么每个段的最大地址空间可达到4GB,所以虚拟地址空间的容量大小为640TB(16K*4GB).TI标志把64 TB的地址空间分成全局地址和局部地址两个空间,分别为32 TB, TI位为0时,访问的是全局地址空间;TI位为1时,访问的是局部地址空间。通常在定义一个GDT,所有任务共享全局地址空间,如果每个进程除了在GDT中存放段外,还需要创建附加的段,则可以创建LDT,独立占有局部地址空间。GDT在内存中的地址和大小存放在gdtr控制寄存器中,当前正在被使用的LDT地址和大小放在ldtr控制寄存器中。

一个逻辑地址如何转换成相应的线性地址。分段单元执行了以下操作:

     1)检查段选择符中的TI字段,以此决定段描述符保存在哪一个描述符表中(GDT还是LDT中)。

     2)段选择符的索引字段乘以8,计算段描述符在描述符表(GDT 或者 LDT,由上一步决定)中的相对地址。描述符表的首地址保存在gdtr控制寄存器或者ldtr控制寄存器中(保存在哪一个寄存器中由上一步决定)。

     3)段描述中的base字段的值就是段基地址,加上逻辑地址,就得到了线性地址。

     逻辑地址转换成线性地址见图五。

为了加快逻辑地址到线性地址的转换,80X86处理器提供的一种附加的非编程的寄存器,用来装64位的段描述符。每当一个段选择符被装入段寄存器时,相应的段描述符就由内存装入到对应的非编程的CPU寄存器中。只要段寄存器的内部不发生变化,就不需要执行上述步骤(1)(2)来获得线性地址,只需要执行步骤(3)即可。

分页单元把线性地址转换成物理地址。在虚地址保护方式下(即控制寄存器CR0 的PE 位为1),控制寄存器CR0 中的最高位PG来决定是否启动分页机制,当PG=1,分页机制有效,可以把线性地址转换为物理地址;当PG=0,分页机制无效,线性地址就直接作为物理地址使用了。32位的线性地址被分成3个部分:最高10位为页目录索引,中间10位页表索引,最低12位偏移量。线性地址的转换分为两步,都基于转换表,第一步的转换表称为页目录表(page directory),第二步的转换表成为页表(page table)。

线性地址被分为以固定长度为单位的组,称为页(page);分页单元把所有的RAM分成固定的长度的组,称为页框(page frame)。每个页框与页打的长度一致,一个页框包含一个页。页框是存储器中的一部分;而页是一个逻辑上的概念,它既指一组线性地址,也指包含在这组地址中的数据,页包含的数据既可以在存储器中,也可以在磁盘中。

一个线性地址如何转换成相应的物理地址。分页单元执行了以下操作:

     1)页目录基地址寄存器CR3提供页目录的页框地址(即页目录基地址),以页目录基地址为开始,加上线性地址中的页目录索引的值,就在页目录表中找到页目录项,从页目录项中可可以得到页表的基地址值(它的低12位为0)。

2)以页表的基地址值开始,加上线性地址中的页表索引的值,得到页框的物理地址(也就是页框的首物理地址)。页框的物理地址加上线性地址的偏移量,就得到了线性地址在页框内的物理地址。

图六表示了两级页表的转换过程。

从80386开始,Intel微处理器的分页单元处理的4KB的页,每一页的起始地址总是在低12位为0的线性地址上。分页管理把线性地址空间中的任何一页映射到物理空间的一页。采用分页管理机制实现线性地址到物理地址转换映射的主要目的是便于实现虚拟存储器。采用二级页表的目的在于减少每个进程页表所需的RAM数量。如果只使用一级页表,那么有2的20次方个表项来表示每个进程的页表,一个表项4个字节则需要4MB RAM来表示所有的页表项。

在两级页表中,有页目录表项和页表项,它们有相同格式,内容稍微不同,如图七所示。

1) 页框地址:一个页的起始地址称作页框地址。由于一页的大小为4KB,所以在一个页表项内,高20 位就是用来说明一个页框地址的,而低端12 位是用来说明页的控制和状态的。在一级页目录内,页框地址就是指向对应页表起始地址;在二级页表内,页框地址则是指向存储器中页的起始地址。

      2) 存在位P:P=1,表示所指的页(页表项)在物理存储器内;P=0,表示所指的页(页表项)不在物理存储器内。在执行一个线性地址转换所需的页表项或是页目录项的P为0,那么分页单元就把该线性地址存放在控制寄存器CR2中,并产生14号异常:缺页异常。

      3) 读/写位R/W:R/W=1 写,否则为读。用来表示对页(页表)的存取权限,它与地址转换无关。

4) 用户/监控程序位U/S:用来表示访问页(页表)所需的特权级。

      5) 访问位A:用来表明该项指出的页是否已被读或写。若目录项中A=1,则表示该项所指出的页表已被访问过;若页表项中A=0,则表示该页表项所指出存储器中的页未被访问过。分页单元从来不重置这个标志,而是必须由操作系统做。

      6) 脏位D:只用于页表项中。每当对一个页框进行写操作时就设置这个标志。

      7) 可用域AVL:该域共3 位,供系统软件设计人员使用。可将与页使用有关的信息放在该域中,帮助分析判断应把哪些页移出存储器。

      8)PWT 和PCD:控制硬件高速缓存处理页(页表)的方式。

(5)转换后援缓冲器TLB

从上面线性地址的转换过程可以看出进行一次地址转换需要访问两次内存:一次访问页目录表,一次访问页表。为了加速地址转换过程,80386在芯片内部设置了一个称为转换后援缓冲器TLB(Translation Lookside Buffer)的部件,如图下图所示。TLB的每项存放着32个线性地址值((线性地址的高20位,即页的基地址)和对应的物理地址值(物理地址的高20位,即页框的基地址),另外还包含页的访问权等属性。当线性地址在转换时,将线性地址的高20位与TLB中的线性地址的值比较。如果找不到,,通过上面的转换方式计算出对应的物理地址,同时该物理地址被存在一个TLB的表项中;如果能找到则可以得到页框的基地址,加上线性地址的低12位即可得到物理地址。由于TLB具有32项,能表示出当前常用的32个页与页框的对应关系,而每页为4KB,因此TLB实际上表示出128K个((32*4KB=128KB))线性地址和物理地址的对应关系。由于程序和数据具有局限性,而TLB中可容纳128K个地址的转换信息,利用TLB进行地址转换有极高的命中率,一般可达98%左右。当CPU的控制寄存器CR3的值被修改时,硬件自动使得TLB的所有的项都无效,因为新的一组页表开始使用了。这样以后对同一个线性地址的转化可以快速得到。

3.虚拟8086方式

      它与实地址方式相比就多了一个可选的分页功能。在该模式下,由段寄存器中的基地址左移动4位后于偏移地址,结果为线性地址。如果启动了分页功能,则要使用分页机制将其转换为物理地址,没有启用则线性地址就是物理地址。

三、Intel 80386 的保护机制

1.段级别保护

      (1)不同任务之间的保护 

      为了保护不同任务,通过将每个任务放置在不同的虚拟地址空间来实现。每个任务中进行定义虚拟地址到物理地址的映射函数,随着任务切换后映射函数也会随着切换。由于每个任务各有一组独立的映射表,即具有不同的地址转换函数,当处理器进行切换并执行新的任务时,为新任务切换任务的转换表是重要的一部分。对于不同的任务,它们可以有相同的虚拟地址,由于有各个的映射函数,所以不同的任务的物理地址是不同的。

      (2)同一任务内的保护

      同一任务内的保护机制更适合于保护操作系统,使操作系统由所有任务共享,并且可在每一任务中对其进行访问不被应用程序破坏。各个任务都可以共享使用的虚拟地址空间,称为全局地址空间;  仅由一个任务使用虚拟地址空间,即不被任何其它任务共享的虚拟地址部分,称为局部地址空间。操作系统在虚拟地址空间的划出一个公共区域,每个任务都可以使用该虚拟地址空间并映射到相同的物理地址上。

      在虚地址保护方式下80386/486 微处理器的段级别保护分为4 级保护。每个任务是分离的,其中特权级0 是最高可靠性的特权级;特权级3 是最低可靠性的特权级。每一特权级都有各自独立的程序堆栈,以避免与共享栈区有关的保护问题。当一个程序从一个特权级切换到另一个特权级执行时,程序使用的堆栈从原特权级的栈段改变为新特权级的栈段。堆栈段寄存器 SS来说,描述符特权级(DPL)必须等于当前代码段的特权级(CPL)。每个存储器段都与一个特权级别相联系,程序只有拥有足够的特权级别才能对相应的段进行访问。特权级别用数字0、1、2和3表示,数字较大的级别具有较低的特权。在比较特权级别时,使用“里面”或“内层”这样的术语表示较高特权级使用“外面”或“外层”这样的术语表示较低特权级别。四种特权级的层次关系如图八所示。

在特权级0 中,通常配置操作系统内核, 主要包括任务和内存管理,任务和I/O 设备间的通信等。在特权级1 中,不属于内核的系统标准服务的程序,比如文件共享、数据通信等。在特权级2 中,通常配置对操作系统进行扩充的用户化的程序,这些是依赖于内核的服务,例如,数据库管理程序或逻辑文件访问系统等。特权级3
分给用户应用程序,在该级别上应用程序之间及它们与操作系统之间都应该互相隔离,互不影响。4 级特权级不是都必须使用的,由操作系统自己决定。

2.页保护机制

Intel 80386提供页级保护。分页机制只区分两种特权级,特权级0、1和2统称为系统特权级,特权级3称为用户特权级。在页目录表项和页表项中的保护属性位R/W和U/S用于对页进行保护。

(1)R/W位表示该表项所指定的页是否可读、写或执行。R/W位对页的写保护只在处理器处于用户特权级时才起作用;如果处理器处于系统特权级时,R/W位被忽略,即总可以读、写或执行。若R/W=1,对表项所指定的页可进行读、写或执行;若R/W=0,对表项所指定的页可读或执行,但不能对该指定的页写入。

      (2)U/S位表示用户/系统属性位,用来表示访问页(页表)所需的特权级。若U/S=1,表项所指定的页是用户级页,可由任何特权级下执行的程序访问;如果U/S=0,表项所指定的页是系统级页,只能由系统特权级下执行的程序访问。

线性地址转换为物理地址的过程中会进行页级保护的检查是,如果违反页保护属性的规定而对页进行访问(读/写/执行),则会引起页异常。[6]

引用及参考资料:

[1]http://space.xingyang.org/?viewnews-1196.html

[2]http://book.51cto.com/art/200812/103208.htm

[3]《深入理解linux内核》(第三版)第二章内存寻址

[4] 第8 章 80386/80486 CPU 的存储器管理.pdf

[5]http://www.itgrass.com/a/compile/hbdyy/200705/21-2959.html

[6]http://hi.baidu.com/hyap/blog/item/28d8fc034142db713812bb7a.html

Intel 80386 微处理器的存储器管理的更多相关文章

  1. Intel 80386 CPU

    一.80386 概述 80386处理器被广泛应用在1980年代中期到1990年代中期的IBM PC相容机中.这些PC机称为「80386电脑」或「386电脑」,有时也简称「80386」或「386」.80 ...

  2. Intel系列微处理器的三种工作模式

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  3. OS存储器管理(一)

    存储器的层次: 分为寄存器.主存(内存)和 辅存(外存)三个层次. 主存:高速缓冲存储器.主存储器.磁盘缓冲存储器, 主存又称为可执行存储器: 辅存:固定磁盘存储器.可移动的外部存储器: 其可长期保存 ...

  4. MMU——存储器管理单元

    更多文档参见:http://pan.baidu.com/s/1qW0hjwo MMU,全称Memory Manage Unit, 中文名——存储器管理单元. 许多年以前,当人们还在使用DOS或是更古老 ...

  5. 【av68676164(p55-p58)】 Intel CPU和Linux内存管理

    7.4.1 Intel CPU物理结构 https://www.cnblogs.com/megachen/p/9768115.html x86实模式 实模式 20位:1M内存空间 地址表示方式:段地址 ...

  6. OS存储器管理(三) 虚拟存储器

    基本概念与实现 1)局部性原理 在一段时间内,运行的作业程序仅访问(涉及到)一部分作业代码,即不会涉及整个地址空间.即在一段时间间隔内,仅装入一部分代码,作业照样能正常运行 2)虚拟存储器的引入 作业 ...

  7. OS存储器管理(二)

    离散分配 分页(Paging),分段,段页式 一.分页   一个进程的物理地址可以是非连续的:   将物理内存分成固定大小的块,称为块(frame): 将逻辑内存分为同样大小的块,称为页(page): ...

  8. 8、Cocos2dx 3.0三,找一个小游戏开发3.0存储器管理的版本号

    重开发人员的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27693365 复杂的内存管理 移动设备上的硬件资源十 ...

  9. ARM“庖丁解牛”之存储器管理单元MMU

    转:http://blog.sina.com.cn/s/blog_a07635070101bcbt.html 最近笔者详细地学习了由杜春雷老师编写的<ARM体系结构与编程>.对ARM存储管 ...

随机推荐

  1. hash_map

    点开一道第是自己oj的第440大关,想a了,一直想却无果,学长一句点醒,开始写hash. 关于这道题呢很无语了,两天卡在这上面,而且有些dalao不到20min就a了.我太菜了. 所以要深入讨论这道题 ...

  2. git 命令详细介绍

    Git 命令详解 Git的基本命令: git pull:从其他的版本库(既可以是远程的也可以是本地的)将代码更新到本地,例如:'git pull origin master'就是将origin这个版本 ...

  3. java JDBC (七) org.apache.commons.dbutils 查询

    package cn.sasa.demo1; import java.sql.Connection; import java.sql.SQLException; import java.util.Li ...

  4. 【pyqtgraph绘图】安装pyqtgraph

    解读官方API-安装 安装 参考:http://www.pyqtgraph.org/documentation/installation.html 根据您的需要,有许多不同的方式来安装pyqtgrap ...

  5. ext.js的mvc

    1.Ext.js的mvc开发模式 在ext.js4.0以后引入mvc开发模式,将js分成model-view-controller三层,使得大量js代码变得更加易于维护和重用,这就是ext.jsmvc ...

  6. 1-3-编译Linux内核

    1-3-编译Linux内核 1.将Linux源码包拷贝到共享文件夹. 2.进入共享文件夹. 3.解压,命令#tar xvfj Kernel_3.0.8_TQ210_for_Linux_v2.2.tar ...

  7. java之httpClient 3.x、AsyncHttpClient1.9.x使用总结

    首先请大牛们见谅菜鸟重复造轮子的学习方式,本文适合新手看~ 下面使用的同步http是HttpClient 3.X的版本,不过早已不在维护,如果刚开始使用http,建议大家都换成4.X版本,别看下面的有 ...

  8. pymongo模块 目录

    MongoDB pymongo模块 MongoDB pymongo模块 查询 MongoDB pymongo模块 插入数据 MongoDB pymongo模块 更新数据 MongoDB pymongo ...

  9. socket 套接字总结

    简单版 服务端 import socket import struct import json import os server_dir = r'E:\Moudule_1\socket练习\serve ...

  10. mongodb studio 3t 破解无限使用脚本

    @echo off ECHO 重置Studio 3T的使用日期...... FOR /f "tokens=1,2,* " %%i IN ('reg query "HKEY ...