一。 段机制:
1。段描述符:
在保护模式下,linux 有三种类型的描述符表,分别为: GDT(全局描述符表),LDT(局部描述符表),IDT(中断描述符表)。
段描述符就是GDT 和 LDT 表中的一个数据结构项,用于向处理器提供有关一个段的位置和大小信息,访问控制状态信息。
在保护模式下描述符由8个字节的数表示。
第5个字节表示 存取权字节。如图所示:
P表示存取位,表示这个段是否在内存中,P=1 表示在内存中,P=0 表示不在。
DPL表示描述符特权级
S表示段是系统段还是用户段。
在保护模式下,段寄存器中应该存放表的索引(段选择符):
段寄存器为16位
0-1 位为RPL 请求者的特权值
第2位为TL 选择相应的段描述符表(局部描述符表或全局描述符表)
3-15 为索引
2.地址的转换
虚拟地址转换成线性地址
a.在段寄存器中装入段选择符同时把32位便宜量某个寄存器(如ESI EDI)
b.根据选择符中的索引值 TI, RPL的值,以及相应段描述符表中的段地址和段界限,进行一系列检查,如果没有问题就取出相应的描述符放入段描述符高速缓冲器中,
c.将描述符中的32位段基址和放在寄存器中的32位有效地址相加,就形成了线性地址。
3.linux中的段:
linux内核的设计并没有全部采用Intel 所提供的段方案,仅仅有限度的用了分段机制,这不仅简化了Linux 内核的设计,而且增加了Linux 的可移植性, 因为很多的 RISC 处理器不支持段机制。
在x86上设计操作系统是无法避免使用段机制的, Linux的设计者让段的基地址为 0 段的界限为 4G 。因此给出的地址就直接是线性地址。
为了给代码段和数据段创建不同的段,而且内核和用户程序的特权级不同,所以linux 内核必须为内核和用户程序创建创建代码段和数据段。
- 4 #define __KERNEL_CS 0x10
- 5 #define __KERNEL_DS 0x18
- 6
- 7 #define __USER_CS 0x23
- 8 #define __USER_DS 0x2B
可以看出linux 尽量减少对段的使用。
二。分页机制
分页机制是完成线性地址对物理地址的转换。
Cr0 寄存器的最高位为分页位,若为0 不允许分页,为1 时允许分页。
页:将线性地址划分成大小相等的片
页面:把物理空间分成与页大小相等的存储块。
分页机制就是页对页面的映射。页表就是这种数据结构。页表项中通常要包含物理页面地址和页的属性。
两级页表:
每个页面的空间为4K ,4G 的空间要被划分成 1M 个页, 没个表项占4 个字节,页表就要占 4M 的连续空间。然而 4M 的页表可以再分(4M / 4K)1K个页。这样通过两级的索引,页表就不用占大的空间。
这样就实现了两级页表。具有两级页表的线性地址的结构如下:
2.页表项的结构:
物理页面的基地址:对页目录而言,指的是页表所在物理页面的起始地址,对页表而言,指的是页所对应物理页面在内存中的起始地址。因此低12位全部为0,就用高20位来描述32位的地址,低12位来描述属性。
第0位:p位,表示页是否装入内存中。
第1-2位:硬件保护位
第3位:是否采用写透方式,写透方式就是即写内存也写缓存。
第4位:表示是否启用高速缓存
第5位:访问位,对相应的物理内存进行访问该位为1
第9-11:是由操作系统专用。
阅读(2636) | 评论(0) | 转发(1) |