第四章-保护模式

Ⅰ.实模式和保护模式区别辨析

1.实模式和保护模式是针对CPU访存而言的,具体区别如下:

  1. 实模式没有特权级,操作系统和用户程序特权级未加以区分;
  2. 实模式中程序地址是真实的物理地址,用户可以随意指定程序运行位置[段基地址<<0x1+偏移地址得到20位访存地址]
  3. 内存空间对用户全部开放,允许用户随意修改内存空间;
  4. 实模式只适用于单道处理系统,不满足应用需求;
  5. 实模式访存超过64M后,段基地址需要频繁切换;
  6. 实模式地址总线只有20根,最大内存也只有1M,不满足使用需求;

2.保护模式与实模式相比,具有以下优点

  1. 加上了特权级划分,用户程序分配最低特权级3,内核分配最高特权级0,用户程序只可以通过系统调用访问内核,保护了内核的稳定性;
  2. 建立了段描述符表CPU通过段选择子匹配段描述符表获取物理地址访存,实现逻辑地址和物理地址的映射关系;
  3. 寄存器扩展使得寻址空间变宽了,从实模式的16位,到过渡保护模式的24位,再到保护模式的32位内存空间寻址;

Ⅱ.保护模式进阶方案

1.保护模式的寄存器寻址

实模式支持基址寻址、变址寻址、基址变址寻址,但每个寄存器对应固定的的功能,基址寄存器只能是bx,bp,变址寄存器只能是si,di,且bx的段基地址寄存器只能是ds,对应数据段读取;bp的段基地址寄存器只能是sp,对应栈读取。并且操作的立即数只能是16位,超出16位编译器就会报错。

保护模式支持从任意一个通用寄存器取值作为基址和变址,除esp之外。同时支持变址地址乘上比例因子(1,2,4,8)。

2.保护模式之运行模式反转

32位保护模式下的CPU兼容16位实模式程序,主要区别在于内存段的访问方式、寻址方式、物理的寄存器编码不一样,因此需要在编译时通过伪指令bits 16/32指定CPU运行模式,确保程序中寄存器编码、地址等信息的正确编译,让CPU正确执行程序。

(1)32位保护模式的CPU,如何实现实模式下的内存访问呢?

32位保护模式的CPU切换到实模式下时,段基址左移 4 位后的结果就被放入段描述符缓冲寄存器中,以后每次引用一个段时,就直接走段描述符缓冲寄存器,直到该段寄存器被重新赋值。

(2)为什么编译器不可以根据程序开启保护模式代码,自动确定程序运行模式?

保护模式的开启过程如下:

  • 开启A20总线
  • cr0寄存器的pe值置1
  • 设置GDT表。

由于这三个步骤以及每个步骤下面的小阶段不指定顺序,且可以不连续执行,处于交叉执行的状态,因此编译器很难甄别出程序是否含有开启保护模式的过程。

(3)其他

在保护模式每次压入 16 位数据时栈指针 esp 就减 2,每次压入 32 位数据时栈指针 esp 就减 4 。

Ⅲ.全局描述符表GDT

GDT表存放在内存中,相当于是一个数组,每个元素是8Byte的段描述符,存储的是保护模式下数据的访存地址信息,如段基地址、段界限等。操作系统根据指令的段选择子检索GDT表,得到访存地址。

1.段选择子

CPU从访问GDT表请求中取出段选择子,根据段选择子的特权级、访问GDT/LDT类别、段描述符表索引值,来检索GDT/LDT表。

复制代码
RPL,即请求特权级,存在 0、 1 、 2、 3 四种特权级。

段选择子的第 2 位是 TI位,即 Table Indicator,用来指示选择子是在 GDT 中,还是 LDT 中索引描述符。 TI为 0 表示在 GDT 中索引描述符, TI 为 1 表示在 LDT 中索引描述符。

段选择子的高 13 位,即第 3~ 15 位是描述符的索引值,用此值在 GDT 中索引描述符。

2.段描述符

GDT表中的段描述符存有段基地址、段界限(段限长)、类别、特权级等信息,通过段选择子访问,返回段基地址。

3.GDT表的访问

通过访问专门的GDTR寄存器访问GDT表,支持通过lgdt指令设置GDTR寄存器,访问GDTR寄存器可以得到GDT的内存地址和大小。

通过lgdt命令访问

复制代码
lgdt 48 位内存数据  

实模式下建立GDT表后,系统进入保护模式,但进入保护模式之后,需要重新建立GDT表。在保护模式下重新换个 GDT 的原因是实模式下只能访问低端 IMB 空间,所以 GDT 只能位于 IMB 之内。根据操作系统的实际情况,有可能需要把 GDT 放在其他的内存位置,所以在进入保护模式后,访问的内存空间突破了 IMB,可以将 GDT 放在合适的位置后再重新加载进来。 【保护模式将内核文件放入内存的0号地址】

与GDT类似,LDT同样也是存放于内存中,LDT是每个任务的私有自己的段描述符表 。通过LDTR寄存器访问LDT,通过lldt指令设置LDT表

复制代码
lldt 16 位寄存器/16 位内存

对于GDT而言,未经初始化的GDT段选择子的索引值为0,为了保证未初始化的段选择子能被识别,因此GDT的0号索引值为空,并触发一个中断。但是LDT一旦建立,说明程序完整,因此LDT表的0号索引值不为空,对应的真实的段基地址。

Ⅳ.打开A20地址线

A20地址线对应的是第21根地址总线,实模式下只有20根,所以打开A20地址线意味着开启保护模式

实模式下,由于逻辑地址就是物理地址,因此当逻辑地址超过了物理地址的范围时,通过地址回绕的方式保证正常寻址,CPU 采取的做法是将超过1MB的部分自动回绕到 0 地址,继续从 0 地址开始映射。 相当于把地址对 1 MB求模。 超过 1MB 但多余出来的内存被称为高端内存区 HMA 。 而保护模式下就直接访问超过1MB的地址,根据如下原则:

  • 如果 A20Gate 被打开,当访问到 0x100000~0x10FFEF 之间的地址时, CPU 将真正访问这块物理内存。
  • 如果 A20Gate 被禁止,当访问 0x100000~0x10FFEF 之间的地址时, CPU 将采用 8086/8088 的地址回绕。

A20地址线打开方式将0x92的第1位置1即可(从0开始编号)

复制代码
in al,0x92

or al,0000_0010B

out ox92,al

Ⅴ.CR0寄存器PE值置1

控制寄存器是 CPU 的窗口,既可以用来展示 CPU的内部状态,也可用于控制 CPU 的运行机制。这次我们要用到的是 CR0寄存器。更准确地说,我们要用到 CR0寄存器的第 0 位,即 PE 位, Protetion Enable,此位用于启用保护模式,是保护模式的开关,具体设置代码如下:

复制代码
mov eax,cr0
or eax,0x00000001
out cr0,eax

平坦模型就是整个内存都在一个段里,不用再像实模式那样用切换段基址的方式访问整个地址空间。

Ⅵ.重新配置保护模式下GDT表

实模式的内存空间只有1MB,因此实模式建立的GDT表只在内存的低1MB空间内,当系统进入保护模式后,内核系统文件将被放置到内存的0号地址内,为了预留足够的空间,因此需要重新配置和放置GDT表。

相关推荐
lyh134427 分钟前
【Ubuntu崩溃修复】
linux·运维·服务器
什么半岛铁盒2 小时前
【Linux系统】Linux环境变量:系统配置的隐形指挥官
linux
Lw老王要学习2 小时前
Linux容器篇、第一章_02Rocky9.5 系统下 Docker 的持久化操作与 Dockerfile 指令详解
linux·运维·docker·容器·云计算
橙子小哥的代码世界2 小时前
【大模型RAG】Docker 一键部署 Milvus 完整攻略
linux·docker·大模型·milvus·向量数据库·rag
倔强的石头1063 小时前
【Linux指南】用户与系统基础操作
linux·运维·服务器
云上艺旅3 小时前
centos升级内核
linux·运维·centos
kaikaile19953 小时前
centos开启samba服务
linux·运维·centos
云上艺旅3 小时前
centos部署k8s v1.33版本
linux·云原生·kubernetes·centos
好多知识都想学3 小时前
Centos 7 服务器部署多网站
linux·服务器·centos
好多知识都想学3 小时前
centos 7 部署awstats 网站访问检测
linux·运维·centos