本文参考书籍

1.操作系统真相还原
2.Linux内核完全剖析:基于0.12内核
3.x86汇编语言  从实模式到保护模式
ps:基于x86硬件的pc系统

保护模式相关介绍

从实模式进入保护模式其实经历三个步骤就可以了,第一步,加载gdt,第二步,打开A20,第三步,置cro为1.

gdt介绍

首先简单介绍一下保护模式下的分段机制
由于在保护模式下,访问地址也是通过段基址加段内偏移来实现的,由于32位寄存器的寻址能力就是4GB,在保护模式下,段赋予了更多的属性和检查,以达到对代码、数据结构、程序和任务的保护。
分段机制就是把虚拟地址空间中的虚拟内存组织成一些长度可变的称为段的内存块单元。80386虚拟地址空间中的虚拟地址由一个段部分和一个偏移部分构成。段是虚拟地址到线性地址转换机制的基础。
每个段由以下几个参数定义;
1、段基址:指定段在线性地址空间中的开始地址,基地址是线性地址,对应于段中偏移0处;
2、段限长:是虚拟地址空间中段内最大可用偏移位置,定义了段的长度;
3、段属性:指定段的特性,例如段是否可读、可写或段的特权级等。
段限长定义了在虚拟地址空间中段的大小,段基址和段限长定义了段所映射的线性地址范围或区域。段内0到limit的地址范围对应线性地址中的base到base+limit。偏移量大于段限长地址是无意义的,多个段映射到线性地址中的范围可以部分重叠或覆盖。
段的基地址、段限长以及段的保护属性存储在一个称为段描述符的结构项中。在逻辑地址到线性地址的转换映射过程中会使用这个段描述符。
逻辑地址由16位的段选择符和32位的偏移量构成,如图所示;段选择符指定字节所在段,而偏移量指定该字节在段中相对于段基地址的位置。

为了把逻辑地址转换成一个线性地址,一般会执行以下操作;
1、使用段选择符中的偏移值在GDT或LDT表中定位相应的段描述符;
2、利用段描述符检验段的访问权限和范围,以确保该段是可访问的并且偏移量位于段界限内;
3、把段描述符中取得的段基地址加到偏移量上,最后形成一个线性地址。
如果没有开启分页,那么处理器直接把线性地址映射到物理地址,如果对线性地址空间进行了分页处理,那么就会使用二级地址转换把线性地址转换成物理地址。

段描述符表
段描述符表是段描述符的一个数组,如图所示,段描述符的长度可变,最多包含8192个8字节描述符,由于gdt的低16位是界限值,选择子一个是8字节所以,2的16次方除以8字节就是8192个,锁一个段描述符表最大包含8192个段描述符。描述符表又分为两种:全局描述符表GDT和局部描述符表LDT。

段选择符
段选择符是段的一个16位标识符,段选择符并不直接指向段,而是指向段描述符表中定义段的段描述符,段选择符的3个字段分别是请求特权级RPL、表指示标志T1、索引值。请求特权级字段RPL提供了段保护信息,表所以字段TI用来指出包含指定段描述符的段描述符表GDT或LDT,索引字段给出了描述符在GDT或LDT表中的索引项号。

段描述符
段描述符用于向处理器提供有关一个段的位置和大小信息以及访问控制的状态信息,如图所示。每个段描述符的长度是8个字节,含有三个主要字段:段基址、段限长和段属性。段描述符通常由编译器、链接器、加载器或者操作系统创建。有关段描述符中的具体含义可自行了解。

A20地址线

实模式下内存访问采用了段基址加段内偏移,由于在实模式下地址线是20位,最大寻址空间是1MB,超出1MB内存的部分在逻辑上也是正常的,但物理内存却没有对应的部分,为了解决该问题,cpu采取了将超过1MB的部分自动回绕到0地址,继续从0地址开始映射,相当于把地址对1MB求摸,超过1MB多余出来的内存被称为高端内存区HMA。

对于只有20位地址总线的cpu,不需要任何额外的操作便能自动实现地址回绕。由于地址进位到1MB以上,如0x100000,由于没有多余的地址线,相当于进位丢失,变成了0x00000,所以实现了自动回绕。
对于后续cpu通过20GATE来控制A20地址线,如果有该总线,当该地址线是开启的时候,如果访问0x100000~0x10FFEF之间的内存时,系统将直接访问这块物理内存,并不会像20根总线那样回绕。
为了解决此问题的第21根地址线就称为A20GATE;
如果A20GATE被打开,当访问0x100000~0x10FFEF之间的地址时,cpu将访问这块物理内存。
如果A20GATE被禁止,当访问0x100000~0x10FFEF之间的地址时,cpu将地址回绕。

保护模式的开关,cro寄存器的PE位

CR0寄存器的第0位,即PE位,此为用于启动保护模式,是保护模式的开关。

相关代码如下;

   %include "boot.inc"section loader vstart=LOADER_BASE_ADDRLOADER_STACK_TOP equ LOADER_BASE_ADDRjmp loader_start                 ; 此处的物理地址是:;构建gdt及其内部的描述符GDT_BASE:   dd    0x00000000 dd    0x00000000CODE_DESC:  dd    0x0000FFFF dd    DESC_CODE_HIGH4DATA_STACK_DESC:  dd    0x0000FFFFdd    DESC_DATA_HIGH4VIDEO_DESC: dd    0x80000007        ;limit=(0xbffff-0xb8000)/4k=0x7dd    DESC_VIDEO_HIGH4  ; 此时dpl已改为0GDT_SIZE   equ   $ - GDT_BASEGDT_LIMIT   equ   GDT_SIZE - 1 times 60 dq 0                     ; 此处预留60个描述符的slotSELECTOR_CODE equ (0x0001<<3) + TI_GDT + RPL0         ; 相当于(CODE_DESC - GDT_BASE)/8 + TI_GDT + RPL0SELECTOR_DATA equ (0x0002<<3) + TI_GDT + RPL0     ; 同上SELECTOR_VIDEO equ (0x0003<<3) + TI_GDT + RPL0    ; 同上 ;以下是定义gdt的指针,前2字节是gdt界限,后4字节是gdt起始地址gdt_ptr  dw  GDT_LIMIT dd  GDT_BASEloadermsg db '2 loader in real.'loader_start:;------------------------------------------------------------
;INT 0x10    功能号:0x13    功能描述:打印字符串
;------------------------------------------------------------
;输入:
;AH 子功能号=13H
;BH = 页码
;BL = 属性(若AL=00H或01H)
;CX=字符串长度
;(DH、DL)=坐标(行、列)
;ES:BP=字符串地址
;AL=显示输出方式
;   0——字符串中只含显示字符,其显示属性在BL中。显示后,光标位置不变
;   1——字符串中只含显示字符,其显示属性在BL中。显示后,光标位置改变
;   2——字符串中含显示字符和显示属性。显示后,光标位置不变
;   3——字符串中含显示字符和显示属性。显示后,光标位置改变
;无返回值mov   sp, LOADER_BASE_ADDRmov   bp, loadermsg           ; ES:BP = 字符串地址mov   cx, 17          ; CX = 字符串长度mov   ax, 0x1301      ; AH = 13,  AL = 01hmov   bx, 0x001f      ; 页号为0(BH = 0) 蓝底粉红字(BL = 1fh)mov   dx, 0x1800      ;int   0x10                    ; 10h 号中断;----------------------------------------   准备进入保护模式   ------------------------------------------;1 打开A20;2 加载gdt;3 将cr0的pe位置1;-----------------  打开A20  ----------------in al,0x92or al,0000_0010Bout 0x92,al;-----------------  加载GDT  ----------------lgdt [gdt_ptr];-----------------  cr0第0位置1  ----------------mov eax, cr0or eax, 0x00000001mov cr0, eax;jmp dword SELECTOR_CODE:p_mode_start         ; 刷新流水线,避免分支预测的影响,这种cpu优化策略,最怕jmp跳转,jmp  SELECTOR_CODE:p_mode_start       ; 刷新流水线,避免分支预测的影响,这种cpu优化策略,最怕jmp跳转,; 这将导致之前做的预测失效,从而起到了刷新的作用。[bits 32]
p_mode_start:mov ax, SELECTOR_DATAmov ds, axmov es, axmov ss, axmov esp,LOADER_STACK_TOPmov ax, SELECTOR_VIDEOmov gs, axmov byte [gs:160], 'P'jmp $

按照如上所述步骤进入了32为保护模式。

Linux保护模式初始化过程

保护模式所需要的一些数据结构由处理器内存管理功能确定。处理器支持分段模型,可以使用单个、统一的地址空间平坦模型到每个任务都具有几个手保护地址空间的高度结构化的多段模型。处理器在切换到保护模式运行之前需要先设置好保护模式下使用的数据结构的基本信息,这些数据机构包括以下几种:
1、保护模式中断描述符表IDT;
2、全局描述符表GDT;
3、任务状态表TSS;
4、局部描述符表LDT;
5、若使用分页机制,则需设置页目录和页表;
6、处理器切换到保护模式下运行的代码段;
7、含有中断和异常处理程序的代码模块。
在切换到保护模式之前,软件初始化还必须设置全局描述符表基地址寄存器GDTR、中断描述符表基地址寄存器IDTR和控制寄存器CR1~CR3,在完成了这些操作后,通过设置CR0寄存器的保护模式标志PE(置0),处理器就可以切换到保护模式运行。
在刚进入保护模式中运行时,特权级是0,为了保证程序的兼容性,切换操作应该按照如下步骤进行:
1、禁止中断、使用CLI指令可以禁止可屏蔽硬件中断;
2、执行LGDT指令把GDT表的基地址加载进GDTR寄存器;
3、执行在控制寄存器CR)中设置PE标志;
4、在执行完成CR0指令之后立刻执行一个远跳转JMP或远调用CALL指令,这个操作通常是远跳转到货远调用指令流中的下一条指令;
5、若要使用局部描述符表,则执行LLDT指令把LDT段的选择符加载到LDTR寄存器中;
6、执行LTR指令,用初始保护模式任务的段选择符或者可写内存区域的段描述符加载任务寄存器TR。这个可写内存区域用于在任务切换时存放任务的TSS信息;
7、在进入保护模式后,段寄存器仍然含有在实模式时的内容,需要步骤4中的jmp或call指令重置cs寄存器,执行以下操作之一可以更新其余段寄存器的内容:其余段寄存器的内容可通过重新加载或切换到一个新任务来更新;
8、执行LIDT指令把保护模式IDT表的基地址和长度加载到IDTR寄存器中;
9、执行STI指令开启可屏蔽硬件中断。

Linux的保护模式初始化过程大致经历了如上步骤。

操作系统学习:实模式进入保护模式相关推荐

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

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

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

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

  3. 3.操作系统——CPU的实模式、保护模式和长模式

    有实模式.保护模式.长模式 实模式16(实地址模式) 真实分为两个方面: 运行真实指令.不区分指令动作,只是直接执行指令的真实功能 发往内存的地址是真实.不加限制的. 总结来说就是,这个模式下直接往物 ...

  4. 操作系统:浅谈实模式,保护模式与长模式

    学习了操作系统的实模式.保护模式与长模式,此文作为回顾. x86 CPU 在第一次加电和每次 reset 后,都会自动进入实模式,要想进入保护模式,就需要程序员写代码实现从实模式切换到保护模式. 一. ...

  5. (操作系统开发)从实模式---->保护模式---->IA-32e模式( 64位模式)

    实模式和保护模式都是CPU的工作模式. 实模式与保护模式介绍 在实模式下,程序可以操作任何地址空间,而且无法限制程序的执行权限.尽管这种模式给设置硬件功能带来许多方便,但却给程序执行的安全性和稳定性带 ...

  6. 【操作系统 3.了解实模式与保护模式的区别】

    一.实模式与保护模式鸟瞰 我这人喜欢直面问题,其实本章只需要搞明白三个主要问题就行了, 什么是实模式和保护模式, 实模式与保护模式的区别是什么, 怎么进入保护模式. 我先来简单阐述下这三个问题 什么是 ...

  7. 实模式和保护模式区别及寻址方式

    64KB-4GB-64TB? 我记得大学的汇编课程.组成原理课里老师讲过实模式和保护模式的区别,在很多书本上也有谈及,无奈本人理解和感悟能力实在太差,在很长一段时间里都没真正的明白它们的内含,更别说为 ...

  8. 任务切换——《x86汇编语言:从实模式到保护模式》读书笔记38

    任务切换--<x86汇编语言:从实模式到保护模式>读书笔记38 本文及后面的几篇博文是原书第15章的学习笔记. 本章依然使用第13章的主引导程序. 1. 协同式多任务与抢占式多任务 有两种 ...

  9. x86从实模式到保护模式实验说明

    在做完王爽<汇编语言>所有实验后,到这里进入到操作系统的层面了.作为一个数学系的研究生自学计算机,摸索了很长时间后,感觉一个靠谱的路线是:先学会一门语言对计算机有一个感觉,能做点事情--& ...

最新文章

  1. centos上安装anaconda并配置虚拟环境
  2. 趁周末,来学点进阶知识:Java 动态编译
  3. 绝对强大的三个LINUX指令: AR, NM, OBJDUMP
  4. sublime3在windows下面无法关联.py文件解决方案(转载)
  5. eclipse的servlet默认不执行index_MySQL之索引及执行计划分析
  6. 利用display属性写的遮罩层
  7. mysql maria引擎_MySQL/MariaDB---查询缓存与存储引擎
  8. 我是如何将系统QPS从300提升到6000的
  9. ca 自建 颁发证书_自建 ca 及使用 ca 颁发证书
  10. dmv io读写高的sql_使用内置的动态管理视图(DMV)发现更多SQL Server信息
  11. Timer源码之TaskQueue
  12. html页面缩小布局乱了为什么啊_PPT页面总是太空?这4个方法,让你的PPT增加亿点点细节!...
  13. 手机圈老兵任伟光加盟联想
  14. DevExpress控件TExtLookupComboBox实现多列模糊匹配输入的方法
  15. [个人笔记] 关于linux的常见问题合集
  16. NVMe的Linux内核驱动分析
  17. 安装MapGIS IGServer遇到的问题
  18. 编程猫python教学_有老师使用过编程猫进行教学吗?
  19. 摄像头P2P软件提供,完美解决打洞及音视频、用户码传输问题。
  20. 前端面试题:金山办公2020校招前端开发工程师笔试题(一)

热门文章

  1. 深度学习三巨头共同发文,聊聊深度学习的过去、现在与未来
  2. 10 行代码玩转 NumPy!
  3. 最高3000元/人 , 助你成为C站红人 !
  4. Facebook面经全披露,我是怎么拿到机器学习工程师offer的?
  5. 针对《评人工智能如何走向新阶段》一文,继续发布国内外的跟贴留言439-448条如下:
  6. 腾讯Angel升级:加入图算法,支持十亿节点、千亿边规模!中国首个毕业于Linux AI基金会的开源项目...
  7. 超越最新无监督域自适应方法,研究人员提轻量CNN新架构OSNet
  8. 一文看尽目标检测:从YOLO v1到v3的进化之路
  9. 程序员,快通知你们老板上吴恩达的最新AI课
  10. 架构师实践日 · 6.30 杭州站 | 视觉 AI 技术如何助力行业提升?来西子湖畔与业内大咖面对面交流!