段式内存管理和页式内存管理

段式内存管理和页式内存管理
(1)80386的段式内存管理机制
首先,在80386CPU中增设了两个寄存器:一个是全局性的段描述表寄存器GDTR,另一个是局部性的段描述表寄存器LDTR,分别可以用来执行存储在内存中的一个段描述结构数组,或者称为段描述表。访问这两个寄存器的专用指令设计成“特权指令”
在此基础上,段寄存器的高13位用作访问段描述表中具体描述结构的下标。GDTR或LDTR中的段描述表指针和段寄存器中给出的下标结合在一起,才决定了具体的段表述表项在内存中的什么地方。每个段描述表项的大小是8个字节,每个描述表项含有段的基地址和段的大小,再加上其他一些信息
每当一个寄存器的内容发生改变时,CPU就把由这段寄存器的新内容所决定的段描述项装入CPU内部的一个影子描述项。这样,CPU中有几个段寄存器就有几个影子描述项,所以也可以看作是对段寄存器的扩充。扩充后的段寄存器分成两部分,一部分是可见的(对程序而言),还与原先的段寄存器一样;另一部分是不可见的,就是用来存放影子描述项的空间,这一部分是专供CPU内部使用的
在80386的段式内存管理的基础上,如果把每个段寄存器都指向同一个描述项,而在该描述项中则将基地址设成0,并将段长度设成最大,这样便形成一个从0开始覆盖整个32位地址空间的一个整段。由于基地址为0,此时的物理地址与逻辑地址相同,CPU放到地址总线上去的地址就是在指令中给出的地址。这样的地址有别于由“段寄存器/位移量”构成的层次式地址,所以Intel称其为平面地址。
利用80386对段式内存管理的硬件支持,可以实现段式虚存管理。当一个段寄存器的内容改变时,CPU要根据新的段寄存器内存以及GDTR或LDTR的内容找到相应的段描述项并将其装入CPU中。在此过程中,CPU会检查该描述项中的p标志位,如果p标志为0,就表示该描述项所指向的那一段内容不在内存中(在磁盘上的某个地方),此时CPU会产生一次异常,而相应的服务程序便可以从磁盘交换区将这一段的内容读入内存中的某个地方,并据此设置描述项中的基地址,再将p标志位设置成1。相应地,内存中暂时不用的存储段则可以写入磁盘,并将其描述项中p标志位改为0
对段式内存管理的支持只是i386保护模式的一个组成部分,如果没有系统状态和用户状态的分离,以及特权指令(只允许在系统状态下使用)的设立,那么尽管有了段式内存管理,也不能起到保护的效果
80386将执行权限划分4个特权级别,其中0级最高,3级最低。每一条指令也都有其适用界别。一般程序的当前运行级别由其代码段的局部描述项中的dpl字段决定。每个描述项中的dpl字段都是在0级状态下由内核设定的。而全局段描述的dpl字段,表示所需的级别
段寄存器中的高13位用作下标来访问段描述表,ti(1位)为1时,表示要使用全局段描述表,为0时,表示使用局部段描述表。rpl(2位)表示所要求的权限。当改变一个段寄存器的内容时,CPU会加以检查,以确保该段程序的当前执行权限和段寄存器所指定要求的权限均不低于所要访问的那一段内存的权限dpl
(2)i386的页式内存管理机制
80386的系统结构决定了它的页式存管只能建立在段式存管的基础上,页式管理的作用是由段式存管所映射而成的地址上再加上一层地址映射,由于此时由段式存管映射而成的地址不再是“物理地址”了,Intel就称之为“线性地址”。于是,段式存管先将逻辑地址映射成线性地址,然后再由页式存管将线性地址映射成物理地址;或者,当不使用页式存管时,就将线性地址直接用作物理地址
80386把线性地址空间划分为4K字节的页面,每个页面可以被映射至物理存储空间中任意一块4K字节大小的区间。在段式存管中,连续的逻辑地址经过映射后在线性地址空间还是连续的。但是在页式存管中,连续的线性地址经过映射后在物理空间却不一定连续
由于页式存管的引入,对32位的线性地址有了新的解释(以前就是物理地址):
线性地址:页面目录dir(10位)+页面表page(10位)+页内偏移offset(12位)
在页面目录中共有1024个目录项,每个目录项指向一个页面表,而在每个页面表中又共有1024个页面描述项。类似于GDTR和LDTR,又增加了一个新的寄存器CR3作为指向当前页面目录的指针。这样,从线性地址到物理地址的映射过程为:
从CR3取得页面目录的基地址
以线性地址中的dir位段为下标,在目录中取得相应页面表的基地址
以线性地址中的page位段为下标,在所得到的页面表中取得相应的页面描述项
将页面描述项中给出的页面基地址与线性地址空间中的offset位段相加得到物理地址

一个页面的大小是4K字节,而每一个页面表项或目录表项的大小是4个字节,1024个表项正好是4K字节,恰好可以放在一个页面中
目录项中含有一个指向页面表的指针,而页面表项中则含有指向一个页面起始地址的指针。由于页面表和页面的起始地址都总是在4K字节的边界上,这些指针的低12位永远都是0。这样,在目录项和页表项中都只要有20位用于指针就够了,余下的12位可用于控制或其他目的
目录项结构:
ptba(20位):页表基地址的高20位
avail(3位):供系统程序员使用
g(1位):全局性页面
ps(1位):页面大小,0表示4K字节
reserved(1位):保留,永远是0
a(1位):已被访问过
pcd(1位):不使用缓冲存储器
pwt(1位):用于缓冲存储器
u_s(1位):为0表示系统权限,为1表示用户权限
r_w(1位):只读或只写
p(1位):为0表示相应的页面不在主存中
页表项的结构基本上与此相同,但没有“页面大小”位ps,所以第8位保留不用,但第7位(在目录项中保留不用)则为D标志,表示该页面已经被写过,所以已经脏了。当页面表项中的最低位p为0时,表示相应的页面或页面表不在内存,根据其他一些有关寄存器的设置,CPU可以产生一个“页面错”异常。这样,内核中的有关异常服务程序就可以从磁盘上的页面交换区将相应的页面读入内存,并且设置表项的基地址,并将p位设置成1。相反,也可以将内存中暂不使用的页面写入磁盘的交换区,然后将相应页面表项的p位设置为0。这样,就可以实现页面虚存了
 

没有更多推荐了,返回首页