80x86保护模式及其编程之内存管理与保护

来源:互联网 发布:golang url encode 编辑:程序博客网 时间:2024/06/05 00:45

80x86的基础知识包括:

保护模式内存管理,各种保护措施,中断和异常管理,任务管理

80x86系统寄存器和系统指令

  1. 标志寄存器:用于控制I/O访问、可屏蔽硬件中断,调式、任务切换以及虚拟8086模式
  2. 内存管理器:GDTR,LDTR,IDTR,TR,用于指定内存分组管理所用系统表的基地址。它们都是段基址寄存器,这些段含有分段机制的重要信息表。GDTR,LDTR,IDTR,用来存放描述符表的段。TR用于包含一个特殊的任务状态段。
  3. 控制寄存器:用于控制和确定处理器的操作模式以及当前执行任务的特性。其中CR0中的保护控制位很重要,PE:启用保护模式标志(开启分段模式),复位就进入实地址模式。PG:代表是否分页,禁止分页的时候,线性地址等于物理地址。CR2,CR3用于分页模式。CR3存放页目录表页面的物理地址。为了减少地址转换的周期,最近访问的页目录和页表会存放在处理器的TLB
  4. 大多数系统指令只能由特权级0的操作系统软件执行

保护模式内存管理

内存寻址:

  1. 80x86是先存小值的处理器
  2. 为了内存寻址,采用了段的寻址技术。逻辑地址:段地址(16位)+段偏移(32位)组成
  3. CS,DS,ES,SS,FS,GS存放段选择符,即段基址

地址变换

  1. 地址变换能够让操作系统在给任务分配时具有灵活性,并且因为我们可以让某些物理地址不被任何逻辑地址映射,那么也提供了内存保护功能
  2. 将逻辑地址映射到物理地址,两种广泛应用技术:分段和分页。

  3. 分段机制:隔绝各个代码、数据和堆栈区域的机制,因此多个程序(或任务)可以运行在同一个处理器而不互相干扰。为传统页需求、虚拟内存系统提供了实现机制
  4. 虚拟内存系统用于实现程序代码按要求被映射到物理内存中

  5. 段描述符指明段的大小、访问权限和段的特权级、段类型以及段的第1字节在线性地址中的位置
  6. 如果禁用分页机制,那么线性地址就是物理地址
  7. 多任务系统的线性空间一般比其物理内存容量大的多,所以使用某种“虚拟化”线性地址空间方法,即虚拟存储技术。
  8. 分页机制支持虚拟存储技术。在虚拟存储的环境中,大容量的线性地址空间需要使用小块的物理内存以及外部存储空间(如大容量硬盘)模拟。
  9. 当使用分页的时候,每个段被划分成页面(每页通常4kb),被存储在内存或是硬盘中
  10. 分页机制会使用固定大小的内存块,而分段管理使用了大小可变的块管理内存。
  11. 分段和分页是两种不同的地址变换机制。都使用了存储在内存中的表,但表的结构不同。实际上,段表存储在线性地址空间,而页表存储在物理地址空间

保护(简单说明)

  1. 80x86提供两种保护。一是:利用不同的虚拟地址隔离各个任务。其二是对任务进行操作,保护操作系统内存段和处理器特殊系统寄存器不被应用程序访问
  2. 保护一:每个任务有其独自的映射表,因此具有不同的地址变换函数。任务切换的关键在于:切换到新任务的变换表
  3. 通过在所有任务中安排具有相同的虚拟空间到物理空间映射的部分,并把操作系统存储在这个公共区域部分,这样操作系统可以被所有任务共享(当不运行任何任务的时候,内存也有不少被占用,就是操作系统占用内存)。即全局地址空间。每个任务唯一的虚拟地址空间被称为局部地址空间,具有相同的虚拟地址也将被映射到不同的物理地址。
  4. 特权级保护:4个执行特权级。0具有最高级别。每个内存段都与一个特权级相关联,从CS寄存器中可得知当前任务的特权级,当一个程序访问一个段的时候,当前特权级会与段的特权级进行比较,从而确定是否可以访问。每个特权级都有自己的程序栈,以避免共享栈带来的保护问题。(堆栈切换)当一个程序从一个特权级切换到另一个特权级的时候,堆栈段也切换到新级别的堆栈中。

分段机制

  1. 段的参数:段基址,段限长,段属性,存储在段描述符中
  2. 段描述符表:GDT(全局) LDT(局部:)虚拟地址空间被分割为大小相等的两半,一半由GDT映射,一半由LDT映射。任务切换的时候,LDT更新,GDT不变,所以GDT映射的空间是所有任务共有的。

  3. 当任务A运行时,可访问的包括LDTA映射的CodeA和DataA段,加上GDTA映射的系统段,此时B不是虚拟地址空间的部分,因此任务A无法访问B的内存
  4. GDT必须含有LDT的段描述符
  5. 段选择符(16位):包括三个字。请求特权级(RPL),表指示标志TI,索引值。用来锁定表中的段描述符,并且在描述符中得到一个段的所有信息
  6. 访问某个程序段,必须把段选择符加载到一个段寄存器中。
  7. 段描述符通常由编译器、链接器、加载器或者操作系统创建,绝对不是应用程序。
  8. 段描述符包括段限长,基地址、段属性。段属性。段属性包括指明这是个系统段还是代码数据段,访问级别,段存在标志....。
  9. 当描述符是代码段或是数据段的时候。数据段有已访问、可写、扩展方向标志,加载到SS寄存器的堆栈段必须是可读写数据段。代码段有有已访问、可读和一致性标志。
  10. 一致性(新概念):所有的数据段都是非一致性的,意味它们不能被低特权级的访的程序或者过程访问。需要防止低特权级向高特权级访问就应该放到非一致性代码段中。
  11. 系统描述符类型:LDT段描述符,任务状态段描述符,调用门,中断门,陷阱门,任务门。分为两类:系统描述符和门描述符。

分页机制

  1. 分页是对固定大小的内存块进行操作
  2. 页表中的每个页表项包括了存放页面的物理基地址和页面是否存在的属性。
  3. 由于页表含有1M个表项,每个表项是4B,那么最多占用4MB的内存,为了减少内存占用量,使用两级页表(目录项、页表项)。其实并没有减少内存的使用量,而只是将其分散在内存的各个页面中,不需要连续的4M内存块,并且并不需要为不存在的线性地址空间分配二级页表,只有在需要时分配
  4. 也目录项的存在位可以用于虚拟内存存放二级页表。
  5. 已访问标志和已修改标志同样可以服务于虚拟内存,通过周期性检查,将没有被访问的页面移除到内存外。

保护

  1. 对于分段级保护机制,处理器通过寄存器中的选择符(RPL和CPL)和段描述符中的字段进行保护。对于分页,利用页目录和页表项中的R/W和U/S标志

段级保护

  1. 段限长Limit检查,防止程序寻址到段外的内存位置
  2. 段类型检查。例如某些寄存器只能存放特定类型的描述符

特权级保护:CPL,DPL,RPL(请求特权级,在段选择符中)

  1. 访问数据段时的特权级检查:DPL大于或是等于CPL和RPL时,处理器才会把选择符加载进段寄存器

  2. 当使用堆栈段的时候,所有特权级必须匹配
  3. 代码段转移控制时特权级检查,依赖于以上三个特权级外还有目的代码段描述符的一致性标志
  4. 一致代码段,CPL可以大于DPL,忽略RPL检查,转以后CPL不变,这是唯一的CPL与当前代码段DPL不相同的情况
  5. 非一致代码段程序的控制权只能转到相同特权级的代码段中,除非通过调用门
  6. 调用门(待理解):调用门,陷阱门,中断门,任务门(CSAPP中对这些异常陷阱、中断、故障、终止说的更易懂),调用门可以让代码段中的过程被不同特权级的程序访问。调用门操作符存储在GDT或LDT中,不能放在中端描述符表IDT中
  7. 堆栈切换:每当调用门把程序控制转移到一个更高级别的非一致性代码段时,CPU会自动切换到代码段特权级的堆栈去。堆栈切换的目的为防止高特权级程序由于栈空间不足而引起奔溃,同时为了防止低特权级程序通过共享的堆栈去干扰高特权级程序

页级保户

  1. 通过读写标志和用户/超级用户标志
  2. 分段和分页保护是串联电路