操作系统——认识保护模式

实验目的及内容

  1. 认真阅读章节资料,掌握什么是保护模式,弄清关键数据结构:GDT、descriptor、selector、GDTR, 及其之间关系,阅读pm.inc文件中数据结构以及含义,写出对宏Descriptor的分析
  2. 调试代码,/a/ 掌握从实模式到保护模式的基本方法,画出代码流程图,如果代码/a/中,第71行有dword前缀和没有前缀,编译出来的代码有区别么,为什么,请调试截图。
  3. 调试代码,/b/,掌握GDT的构造与切换,从保护模式切换回实模式方法。
  4. 调试代码,/c/,掌握LDT切换。
  5. 调试代码,/d/掌握一致代码段、非一致代码段、数据段的权限访问规则,掌握CPL、DPL、RPL之间关系,以及段间切换的基本方法。
  6. 调试代码,/e/掌握利用调用门进行特权级变换的转移。

实验器材:

VMware虚拟机+Ubuntu32位

实验步骤:

1.阅读章节资料
2.调试代码a,b,c,d,e
3.根据五组代码的区别,以及其分别对应的功能进行分析。

1.a:

程序大致框架为:

在此之后则进入显存打印结果P;
正常执行代码pmtest1的结果如下

但是

如果将71行的这个位置的dword去除,则会导致bochs闪退报错。
很明显,这里是不能删除的,不然人家也不会写对吧,但到底是因为什么呢?
我们来查看一下编译的二进制代码,虽然只有字节显示我并不能理解其含义,但我们会发现,删除dword之后,编译出的二进制代码相比于之前会短一些。

如果使用jmp SelectorCode32:0:
这样编译出来的只是16位的代码。如果目标地址的偏移不是0,而是一个较大的值,比如jmp SelectorCode32:0x12345678,则 编译后偏移会被截断,只剩下0x5678。

2.b:



调试方式与结果如上,这个程序讲述的是从保护模式切换回实模式的方法。在之前的实验里我们了解了怎么进行从实模式到保护模式的切换,但在实验的结尾我们是以一个死循环结束,从输出也可以看出,他没有弹出一个新的DOS,而是打印完P之后就没有反应。在这个实验里,我们添加了一段代码,使得其在执行完之后可以返回到实模式,弹出一个新的DOS。

从这里开始,保护模式执行完成,返回到实模式中。


跳回实模式之后,程序重新设置各个寄存器的值,关闭A20,开中断。
我们看到,程序打印出两行数字,第一行全部是零,说明开始内存地址5MB处都是0,而下一行已经变成了41 42 43…,
说明写操作成功。十六进制的41、42、43、…、48正是A、B、C、…、H。

3.c:


结果如上,编译、调试过程与之前相似就不做截图了。
这一部分实验主要讲的是LDT的构造与运行。其实我觉得LDT和GDT并没有什么很大区别,从代码中也可以看出:


上图显示的更是极其相似,在GDT中为lgdt,在这则是lldt,其工作也是类似的,就是加载ldtr,操作的是一个选择子。因为比较类似,所以不再多做说明。

4.d:


结果如上。

CPL
CPL是当前执行的程序或任务的特权级。在通常情况下,CPL等于代码所在的段的特权级。在遇到一致代码段时,情况稍稍有点特殊,一致代码段可以被相同或者更低特权级的代码访问。当处理器访问一个与CPL特权级不同的一致代码段时,CPL不会被改变。

DPL
DPL表示段或者门的特权级。它被存储在段描述符或者门描述符的DPL字段中,正如我们先前所看到的那样。当当前代码段试图访问一个段或者门时,DPL将会和CPL以及段或门选择子的RPL相比较,根据段或者门类型的不同,DPL将会被区别对待:
数据段:DPL规定了可以访问此段的最低特权级。比如,一个数据段的DPL是1,那么只有运行在CPL为0或者1的程序才有权访问它。
非一致代码段(不使用调用门的情况下):DPL规定访问此段的特权级。比如,一个非一致代码段的特权级为0,那么只有CPL为0的程序才可以访问它。
调用门:DPL规定了当前执行的程序或任务可以访问此调用门的最低特权级(这与数据段的规则是一致的)。
一致代码段和通过调用门访问的非一致代码段:DPL规定了访问此段的最高特权级。比如,一个一致代码段的DPL是2,那么CPL为0和1的程序将无法访问此段。
TSS:DPL规定了可以访问此TSS的最低特权级(这与数据段的规则是一致的)。
RPL
RPL是通过段选择子的第0位和第1位表现出来的。处理器通过检查RPL和CPL来确认一个访问请求是否合法。即便提出访问请求的段有足够的特权级,如果RPL不够也是不行的。操作系统过程往往用RPL来避免低特权级应用程序访问高特权级段内的数据。当操作系统过程(被调用过程)从一个应用程序(调用过程)接收到一个选择子时,将会把选择子的RPL设成调用者的特权级。于是,当操作系统用这个选择子去访问相应的段时,处理器将会用调用过程的特权级(已经被存到RPL中),而不是更高的操作系统过程的特权级(CPL)进行特权检验。这样,RPL就保证了操作系统不会越俎代庖地代表一个程序去访问一个段,除非这个程序本身是有权限的。

上述是课本上对CPL,DPL,RPL的解释,可以说是清晰的不能再清晰了。刚开始看的时候我不是很明白什么是一致代码段,什么是非一致代码段。简单来说,一致代码段就是操作系统可以被低层访问的代码,非一致代码段就是不能拿出来访问调用的代码。理解了这个之后,我们来看看我们的实验做了什么。

首先我们要知道,这个小实验是想使用调用门。我们来找一找这个调用门的定义。





上面的图分别对应选择子和门的定义。
初始化之后,我们就直接回到他最终打印结果的部分:

首先,call一个门,查看这个门后可以发现,他的最后一句为retf,也就是说在call之后,会返回这个位置继续执行下一部分的,即第二个call。所以我们的实验结果是有一个C一个L的!

5.e:


这个阶段的实验目的为,利用门进行有特权级变换的转移。在分析代码之后我们发现出现了一个新的段ring3。初始化选择子我们跳过。

先来看看ring3的定义,高亮部分的代码很明显是打印一个’3’字符,并使得程序停止。

定义过后,依次将ss,esp,cs,eip压栈,执行retf指令。
我们看到了一个红色的3,说明我们成功进入了ring3!
成功进入ring3之后,我们来试验一下调用门的使用。
但在此之前我们别忘了TSS!

准备完成后,在进行特权级变换之前加载TSS。
运行之后,我们可以看到在字符’3’之前是存在其他字符的,这就意味着在ring3下对门的调用也是成功的。
最后,我们将调用局部任务的代码加入到调用门的目标代码,使得我们的程序能成功返回实模式,这也就是最终结果上显示的3个字符的原因。

6.【Descriptor结构体】有8个字节。共包含Base, Limit, Attr三个参数。

%1表示第一个参数Base(段基址)
后同。

【第1、2字节】组合(word) 表示该段的[段界限①], dw %2 & 0FFFFh ;引用第二个参数去掉高16位

【第3、4、5字节】组合表示该段的[段基址①],dw %1 & 0FFFFh ;先得到第一个参数(段基址)低WORD。接着把第5个字节赋值,db (%1 >> 16) & 0FFh 去掉第3第4个字节的内容.再把剩下的字节赋值

【第6个字节】的内容:

0-3位表示:[段属性]、说明存储段描述符所描述的存储段的具体属性。

4位表示:说明描述符的类型, 对于存储段描述符而言,S=1表示是系统段描述符。

5-6位表示:DPL 该段的特权级别也就是Ring 0-3;

7位表示:P: 存在位。
; P=1 表示描述符对地址转换是有效的,即描述的段在内存当中.
; P=0 表示描述符对地址转换无效,即该段不存在。使用该描述符进行内存访问时会引起异常

【第7个字节】的内容:

0-3位表示:[段界限②]

4位表示:软件可利用位。80386对该位的使用未做规定,Intel公司也保证今后开发生产的处理器只要与80386兼容,就不会对该位的使用做任何定义或规定。

5位表示:0 ;Intel资料也没表示

6位表示:是一个很特殊的位,在描述可执行段、向下扩展数据段或由SS寄存器寻址的段(通常是堆栈段)的三种描述符中的意义各不相同,通常置1

7位表示: 段界限粒度(Granularity)位。
G=0 表示界限粒度为字节;
G=1 表示界限粒度为4K 字节。
注意,界限粒度只对段界限有效,对段基地址无效,段基地址总是以字节为单位。

那么这段宏dw ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh)表示:

取[段界限]参数除去低16位取 高4位,得到【段界限②】

取[段属性]参数的低8位 12-15位(AVL属性等)

属性 1 + 段界限 2 + 属性 2

【第8个字节】的内容:

[段基址②] 、db (%1 >> 24) & 0FFh 取基地址参数的最高8位

课后思考

添加GDT段和LDT段分别进行写入和读、打印字符的功能

我选择了在原有的GDT段和LDT段进行修改,这样省去了初始化和定义选择子的步骤。
新增的GDT段

下面是新增的LDT用来读出之前写入的字符串

自定义2个GDT代码段A、B,分属于不同特权级,功能自定义,要求实现A–>B的跳转,以及B–>A的跳转
先load TSS,布置好栈,然后利用retf指令从高特权级转移到低特权级。

利用调用门从低特权级跳转至高特权级的代码进行运行。

最后结果

操作系统——认识保护模式相关推荐

  1. 操作系统——让操作系统走进保护模式

    操作系统--让操作系统走进保护模式 实验内容: 向软盘镜像文件写入一个你指定的文件,手工读取在磁盘中的信息 在软盘中找到指定的文件,读取其扇区信息 将指定文件装入指定内存区,并执行 学会在bochs中 ...

  2. 自己动手写操作系统--搭建保护模式下的运行环境:bochs下安装freedos

    在进行保护模式的运行环境配置前,先看了了下书上的代码,编译运行结果如下:nasm 3_pmtest1.asm -o pmtest1.bin,可以看到界面出现了红色的 p 字 保护模式环境配置 1:在网 ...

  3. OrangeS一个操作系统的实现--保护模式

    以一段汇编代码介绍操作系统进入保护模式: 编译:▹ nasm pmtest1.asm -o pmtest1.bin 参数:软盘映像a.img和Bochs的配置文件bochsrc 写入:将生成的二进制写 ...

  4. 操作系统学习:实模式进入保护模式

    本文参考书籍 1.操作系统真相还原 2.Linux内核完全剖析:基于0.12内核 3.x86汇编语言 从实模式到保护模式 ps:基于x86硬件的pc系统 保护模式相关介绍 从实模式进入保护模式其实经历 ...

  5. 操作系统引导--从实模式到保护模式

    从开始到保护--系统开机引导 ------没有一个文档能写的通俗易懂,我希望写出来. 开机引导和实模式: 两个星期加上假期吐血整理,所述为计算机的开机引导,其中包括一系列计算机内存设置等等,由于没有老 ...

  6. 我是如何学习写一个操作系统(三):操作系统的启动之保护模式

    前言 上一篇其实已经说完了boot的大致工作,但是Linux在最后进入操作系统之前还有一些操作,比如进入保护模式.在我自己的FragileOS里进入保护模式是在引导程序结束后完成的. 实模式到保护模式 ...

  7. 一步步编写操作系统 25 cpu的保护模式

    在保护模式下,我们将见到很多在实模式下没有的新概念,很多都是cpu硬件原生提供,并且要求的东西,也就是说按照cpu的设计,必须有这些东西cpu才能运行.咱们只要了解它们是什么并且怎么用就行了,不用深入 ...

  8. x86从实模式到保护模式 pdf_【自制操作系统04】从实模式到保护模式

    通过前三章的努力,我们成功将控制权转交给了 loader.asm 这个程序.具体说就是 bios 通过加载并跳转到 0x7c00(IMB大叔们定的) 把控制权转交给了我们操作系统的第一个汇编程序 mb ...

  9. 《自己动手写操作系统》读书笔记——初识保护模式

    <自己动手写操作系统>读书笔记--初识保护模式 http://www.cnblogs.com/pang123hui/archive/2010/11/27/2309930.html 书本第三 ...

最新文章

  1. linux 系统调用会被信号打断的
  2. C语言再学习 -- 输入/输出
  3. 一场开发与视觉的对话引发的思考
  4. 【Android】 Android中适配器简介
  5. 用C语言实现津巴布韦这道算法题?
  6. React之类式组件
  7. 不要等到离职,才明白这些道理
  8. 【TinyML 实践 - 1:What Why TinyML】
  9. webservice接口和restful接口哪个更好?
  10. 【学习笔记】RecyclerView的使用
  11. Flask-WTF CSRF 保护P3
  12. 安装CentOS步骤
  13. 分段Hermite插值推导
  14. 数据分析与Excel
  15. 强网杯2022 pwn 赛题解析——yakagame
  16. Hadoop上路-03_Hadoop JavaAPI
  17. PhpStorm更换主题
  18. TFT显示屏参数设置
  19. ddl是什么意思网络语_DDL(数据定义语言)
  20. 使用Python实现12306自动化抢票

热门文章

  1. 那个「最牛删库跑路事件」的程序员,被判了....
  2. 中国风道德教学课件PPT模板
  3. 路由器转发数据包的封装过程
  4. wps 日期斜杆转横杆
  5. Solaris 的 Secure by Default
  6. 使用91手机助手进行软件图标管理
  7. 2021-10-17-ES2
  8. 锦江酒店(中国区):在变革中拥抱未来 实现高质量发展
  9. 实验一:门电路逻辑功能及测试
  10. 裸奔系列之博科SAN交换机(2)---博科SAN交换机接入(登陆)