80x86 保护运行模式
- 格式:doc
- 大小:78.50 KB
- 文档页数:13
80386简介(一)==============linux的早期版本,也是本课讲解的版本,是在80386上实现的,需要对该CPU先有个粗浅的了解。
重点是保护模式的几个概念。
注意:操作系统是管理硬件的程序,CPU的设计者与操作系统设计者的相互依赖是很强的。
80386是INTEL 1985年推出的CPU芯片,是80x86系列中第一个32位微处理器。
80386的内部和外部数据总线都是32位。
地址总线也是32位,可寻址高达4GB内存。
80386具有实模式、保护模式、虚86(V86)等三种工作方式。
系统加电时自动处于实模式,当操作系统初始化完成,操作系统可将其设为保护模式。
1实模式实模式是为了兼容于8086。
只使用20位地址总线,可寻址1M内存,物理地址=左移4位的段地址+偏移地址,等等,这些内容在“组成原理”中都过。
实模式寻址能力有限,而且不能为操作系统内核提供安全保护,比如它没有管态、目态。
没有为多道程序提供必要的支持,比如没有进程空间的隔离功能。
2保护模式可以使用32位地址总线,可寻址高达4GB内存(含虚存)。
但当时的386电脑一般只配1-8M内存,虚存也很小,有些硬盘本身的容量就不够4G。
保护模式和实模式都使用内存段、中断,但二者有很多不同。
在实模式中内存被划分成段,每个段的大小为64KB,这样段地址可以用16位表示。
有几个段寄存器(CS、DS、SS和ES),物理地址=左移4位的段地址+偏移地址。
而在保护模式下,段是通过一系列被称之为"描述符表"的表所定义的。
段寄存器存储的是指向这些表的指针,段长也不再固定为64位,而是可变的。
用于定义内存段的表有两种:全局描述符表(GDT)和局部描述符表(LDT)。
“描述符”是一个32位的地址指针。
GDT是一个段描述符数组,其中包含所有应用程序都可以使用的基本描述符。
每一个操作系统只定义一个GDT。
LDT也是段描述符的一个数组。
与GDT不同,LDT是一个段,每一个正在运行的进程都有一个自己的LDT。
简述x86cpu运行的4个级别x86CPU是一种基于Intel架构的CPU,它是目前世界上最广泛使用的CPU之一。
x86 CPU运行时会经过4个不同的级别,这些级别分别是用户态、内核态、超级用户态和虚拟8086模式。
本文将详细介绍这4个级别的含义和作用。
一、用户态用户态是指CPU在执行用户程序时所处的状态。
在用户态下,CPU 只能访问用户程序所占用的内存空间,不能访问操作系统内核的内存空间。
这是为了保护操作系统内核不受用户程序的干扰。
用户程序可以使用CPU提供的一些指令和功能,但是不能直接访问硬件资源,必须通过操作系统提供的系统调用来实现。
在用户态下,CPU的权限较低,只能执行受限制的指令和操作。
二、内核态内核态是指CPU在执行操作系统内核代码时所处的状态。
在内核态下,CPU可以访问系统的所有资源,可以执行所有指令和操作。
操作系统内核可以直接访问硬件资源,控制系统的各种设备和资源。
在内核态下,CPU的权限最高,可以执行任何指令和操作。
操作系统内核通常使用特权级别0来表示内核态。
三、超级用户态超级用户态是指CPU在执行特权级别大于0但小于3的代码时所处的状态。
在超级用户态下,CPU可以访问一些受保护的资源,如I/O 端口和DMA控制器等。
超级用户态通常用于执行一些需要较高权限的操作,如设备驱动程序的编写和调试等。
超级用户态的权限介于用户态和内核态之间,不同的操作系统有不同的实现方式。
四、虚拟8086模式虚拟8086模式是一种特殊的模式,它允许在保护模式下运行16位的MS-DOS应用程序。
在虚拟8086模式下,CPU会将当前的代码段和数据段设置为16位模式,并且可以访问整个1MB的内存空间。
虚拟8086模式可以通过软件模拟来实现,也可以通过硬件支持来实现。
总结以上就是x86 CPU运行的4个级别,它们分别是用户态、内核态、超级用户态和虚拟8086模式。
每个级别都有不同的权限和作用,它们共同构成了x86 CPU的运行机制。
【X86】---关于Intel芯⽚架构的发展史---恢复内容开始--- 当你真正的深⼊去⾏⾛在底层的道路上,你就会接触⼤量的⼀些貌似懂的概念性名词,⽐如Intel公司的x86架构,x64等等,⼜或者是当年的386,486等等,唉,有的时候真的是很⿇烦啊,经常看到,但是不指导,甚⾄曾经有过⼀个疑问,为何64bit计算酒称之为x64,但是32bit的就叫做x86,为何不叫x32呢(虽然我指导仅仅就是⼀个名字⽽已,但是我仍然想知道其中原因),看的多了,因此今天得地整理了以下Intel公司发展史,也算是学习了。
本⽂节选⾃⽹络,由作者编辑整理⽽成!谈到处理器,就应该知道著名的摩尔定律(到⽬前为⽌,还是对的)。
摩尔定律:1965年⼽登·摩尔在《电⼦学》杂志(Electronics Magazine)第114页发表了影响科技业⾄今的摩尔定律: 1、集成电路芯⽚上所集成的电路的数⽬,每隔18个⽉就翻⼀番。
2、微处理器的性能每隔18个⽉提⾼⼀倍,⽽价格下降⼆分之⼀。
3、⽤⼀个美元所能买到的电脑性能,每隔18个⽉翻两番。
钟摆理论: 在奇数年,英特尔将会推出新的⼯艺;⽽在偶数年,英特尔则会推出新的架构。
简单的说,就是奇数⼯艺年和偶数架构年的概念。
英特尔的钟摆策略,能够体现英特尔技术变化⽅向。
当有英特尔钟摆往左摆的时候,tick这个策略会更新⼯艺,往右摆的时候,tock会更新处理器微架构。
举个例⼦,05年说tick,英特尔更新从90纳⽶⾛向65纳⽶;06年是tock,⽤英特尔推出酷睿架构,07年⾛向45纳⽶。
值得注意的是,⾸先它不会在⼀年内两个技术同时出现。
每⼀年都可以在上个技术上再提升⼀个规模。
钟摆策略发展趋势⼀般是今年架构、明年⼯艺,是让⼤家循序渐进,⽽且实⾏钟摆策略也是带着整个⾏业按着这个钟摆形成⼀种共同的结构往前⾛。
intel系列CPU及其架构: 本⽂将对intel系列CPU及其架构做简要介绍,CPU(Central processing Unit),⼜称“微处理器(Microprocessor)”,是现代计算机的核⼼部件。
Linux0.11——从实模式到保护模式综述最近在阅读Linux 0.11的源码时,对于setup.s⽂件中设置GDT表的部分不是很理解,后来经过刘国军⽼师的指点,结合赵炯博⼠的《Linux内核完全注释》的第四章《80X86保护模式及其编程》,对于保护模式有了⼀些粗浅的了解和认识。
备忘。
本⽂章主要讲解保护模式的寻址机制与setup.s中的切换部分。
保护模式保护模式运⾏在80286及其之后的所有CPU上,但是为了保证向前兼容性,正常的CPU在启动时并不会默认进⼊保护模式,⽽是会进⼊实模式,随后通过⼀系列设定转⼊保护模式。
在16位实模式下,CPU寻址时使⽤16位段寄存器的内容乘以16当作段基地址,加上16位段偏移地址形成20位的物理地址,所以最⼤寻址仅为1MB字节,最⼤段长度64KB。
在实模式下,所有的段都是可以任意访问的,即任意读、写和执⾏。
虽然在80286点CPU上已经出现了保护模式,但是其寄存器的位宽仍然是16位,只不过其地址线由20位扩⼤到了24位,寻址空间随即扩⼤到了16MB。
真正的32位保护模式出现在80386上,其地址总线和寄存器都是32位宽的,因此寻址空间扩⼤到了4GB。
保护模式下,CPU寻址主要有两种模式,⼀是分段模式,⼆是分段和分页相结合,分页⽆法单独出现。
保护模式的分段模式为每⼀段增加了段属性来限制⽤户程序对内存中⼀些段的操作。
在全局描述符表(GDT)中,每个段的表项存储了⼀个段的基本属性,例如段的基地址、段的界限、段的类型(代码段、数据段)、段的执⾏权限等。
分页模式的出现使得程序员可以编写远远⼤于内存的程序⽽⽆需担⼼内存的容量,在该模式下,内存被划分为“页”存储,磁盘的⼀部分⽤作虚拟内存,当应⽤程序执⾏时需要的某些代码或数据所在的页不在内存中时,CPU就会产⽣⼀个缺页异常,从磁盘中将所需的页调⼊内存中后恢复执⾏,在应⽤程序看来,所需的代码或数据仿佛⼀直存在内存上。
重要数据结构在保护模式中,有⼏个长得很像的名字⼀直是我们⼼头噩梦:GDT、GDTR、LGDT、LDT、LDTR、LLDT……事实上,并不是那么难区分。
80386学习(⼀)80386CPU介绍⼀.80386CPU介绍 Inter80386CPU是Inter公司于1985年推出的第⼀款32位80x86系列的微处理器。
80386的数据总线是32位的,其地址总线也是32位,因⽽最⼤可寻址4GB的存储空间。
80386作为x86系列CPU的⼀员,保持着对更早⽣产的x86CPU的向前兼容。
80386在当时主要为⽀持⾼性能的应⽤领域和多⽤户、多任务操作系统⽽设计,提供了硬件级的特权级保护、多任务切换、内存分页等功能。
80386有三种运⾏模式:实模式、保护模式和虚拟8086模式。
在实模式下,80386和8086的⾏为保持⼀致,只能访问20位(1M)的地址空间,内部实际32位的寄存器也只有低16位有效。
实模式主要是为了兼容运⾏在8086CPU上的程序,所以80386加电后,默认就运⾏在实模式下。
要想充分发挥80386的对于多任务的⽀持功能,需要使80386进⼊保护模式。
保护模式是80286以及后续的x86CPU都具有的⼀种⼯作模式。
保护模式下的80386内存寻址范围达到了硬件设计的上限:2^32byte,即4GB。
保护模式提供了诸如内存保护、内存分页机制以及硬件虚拟存储管理等功能,为多⽤户。
多任务的⾼效、可靠、安全的操作系统实现提供了良好的⽀持。
因此,主流的现代操作系统例如Linux、Windows(Windows95及以后)其内核均运⾏在x86的保护模式之上。
虚拟8086模式的⼯作模式介于实模式和保护模式之间,虚拟8086⽀持多任务、内存分页等功能。
但运⾏的每⼀个独⽴任务均处于实模式之下。
虚拟8086这⼀模式由于其中庸性,应⽤范围相对较⼩。
⼆.80386对于8086的主要改进 80386能够兼容的运⾏之前在8086、80286CPU上运⾏的程序,但80386⽐起16位的8086CPU⽆论是性能还是功能上都有质的提升。
性能⽅⾯的主要改进:更宽的数据总线和地址总线 扩展到32位的地址总线使得80386能够访问更⼤的地址空间,同时32位的数据总线⽐起8086的16位也增加了数据的传输速度。
80x86 保护运行模式80386 概述80386 是一个高级的32 位微处理器,专门用于多任务的操作系统,并为需要高性能的应用所设计。
32位的寄存器和数据通道支持32 位的寻址方式和数据类型,处理器可以寻址最高可达4GB 的物理内存以及64TB(246字节)的虚拟内存。
芯片上的内存管理包括地址转换寄存器、高级多任务硬件、保护机制以及分页虚拟内存机制。
下面针对系统编程,概要说明使用80386 的这些基本原理。
系统寄存器设计用于系统编程的系统寄存器主要包括以下几类:标志寄存器EFALGS;内存管理寄存器;控制寄存器;调试寄存器;测试寄存器。
系统标志寄存器EFLAGS 控制着I/O、可屏蔽中断、调试、任务切换以及保护模式和多任务环境下虚拟8086 程序的执行。
其中主要标志见下图所示。
31 23 15 7 00 0 0 0 0 0 0 0 0 0 0 0 O 0VMRFNTIOPLOFDFIFTFSFZFAFPF1CF其中系统标志:VM –虚拟8086 模式;RF –恢复标志;NT –嵌套任务标志;IO PL – I/O 特权级标志;IF –中断允许标志。
内存管理寄存器有4 个,用于分段内存管理:GDTR –全局描述符表寄存器(Global Descriptor Table Register);LDTR –局部描述符表寄存器(Local Descriptor Table Register);IDTR –中断描述符表寄存器(Interrupt Descriptor Table Register);TR –任务寄存器。
其中前两个寄存器(GDTR,LDTR)分别指向段描述符表GDT 和LDT。
IDTR 寄存器指向中断向量表。
TR 寄存器指向处理器所需的当前任务的信息。
80386 共有4 个控制寄存器,分别是CR0、CR1、CR2 和CR3。
格式见下图所示。
31 23 15 7 0页目录基地址寄存器Page Directory Base Register (PDBR)保留ReservedCR3附录465页异常线性地址Page Fault Linear AddressCR2保留ReservedCR1PG保留ReservedETTSEMMPPECR0控制寄存器CR0 含有系统整体的控制标志。
其中:PE –保护模式开启位(Protection Enable,比特位0)。
如果设置了该比特位,就会使处理器开始在保护模式下运行。
MP –协处理器存在标志(Math Present,比特位1)。
用于控制WAIT 指令的功能,以配合协处理的运行。
EM –仿真控制(Emulation,比特位2)。
指示是否需要仿真协处理器的功能。
TS –任务切换(Task Switch,比特位3)。
每当任务切换时处理器就会设置该比特位,并且在解释协处理器指令之前测试该位。
ET –扩展类型(Extention Type,比特位4)。
该位指出了系统中所含有的协处理器类型(是80287还是80387)。
PG –分页操作(Paging,比特位31)。
该位指示出是否使用页表将线性地址变换成物理地址。
内存管理内存管理主要涉及处理器的内存寻址机制。
80x86 使用两步将一个分段形式的逻辑地址转换为实际物理内存地址。
段变换,将一个由段选择符和段内偏移构成的逻辑地址转换为一个线性地址;页变换,将线性地址转换为对应的物理地址。
该步是可选的。
在分页机制开启时,通过将前面所述的段转换和页转换组合在一起,即实现了从逻辑地址到物理地址的两个转换阶段。
段变换下图示出了处理器是如何将一个逻辑地址转换为线性地址的。
在转换过程中CPU 使用了以下一些数据结构:段描述符(Segment Descriptors);描述符表(Descriptor tables);选择符(Selectors);段寄存器(Segment Registers)。
3112 11 22 21 31基地址选择符偏移值+页目录段描述符描述符表页表项页内偏移值线性地址:逻辑地址:0 015附录466图段变换示意图段描述符段描述符向CPU 提供了将逻辑地址映射为线性地址所必要的信息。
描述符是由程序编译器、链接器、加载器或操作系统创建的。
下图示出了描述符的两种一般格式。
所有种类的描述符都具有这两种格式之一。
段描述符的各个字段的含义如下:31 23 15 7 0基地址(BASE)位31..24G X OAVL限长(LIMIT)位19..16P DPL 1 TYPE A基地址(BASE)位23..164段基地址(BASE) 位15..0 段限长(LIMIT) 位15..0a.用于程序代码段和数据段的描述符31 23 15 7 0基地址(BASE)位31..24G X OAVL限长(LIMIT)位19..16P DPL 0 TYPE基地址(BASE)位23..164段基地址(BASE) 位15..0 段限长(LIMIT) 位15..0b.用于特殊系统段的描述符图描述符的一般格式基地址(BASE):定义段在4GB 线性空间中的位置。
处理器会将基地址的三个部分组合成一个32 位的值。
段限长(LIMIT):定义了段的最大长度。
处理器将组合段限长的两个部分形成一个20 位的值。
处理器会依据颗粒度(Granularity)位字段的值来解释段限长域的实际含义:1. 当以1 字节为单元时,则定义了最高可为1MB 字节的长度;2. 当以4KB 字节为单元时,则定义了最高可为4GB 字节的长度。
在加载时限长值将左移12 位。
颗粒度(Granularity):指定了限长字段值代表的单元含义。
当为0 时,限长单元值为1 字节;当该位为1 时,限长的单元值为4KB 字节。
类型(TYPE):用于区分各种不同类型的描述符。
描述符特权级(Descriptor Privilege Level – DPL):用于保护机制。
共有4 级:0–3。
0 级是最高特权级,3 级是最低特权级。
段存在位(Segment-Present bit – P):如果该位为零,则该描述符无效,不能用于地址变换过程。
当指向该描述符的选择符被加载到段寄存器中时,处理器就会发出一个异常信号。
访问位(Accessed bit – A):当处理器访问过该段时就会设置该比特位。
描述符表段描述符是保存在描述符表中的,有两类描述符表:全局描述符表(Global descriptor table – GDT);局部描述符表(Local descriptor table – LDT)。
附录467描述符表是由8 字节构成的描述符项的内存中的一个数组,见下图所示。
描述符表的长度是可变的,最多可以含有8192(213)个描述符。
但是对于GDT 表,其第一个描述符(索引0)是不用的。
图描述符表示意图处理器是通过使用GDTR 和LDTR 寄存器来定位GDT 表和当前的LDT 表。
这两个寄存器以线性地址的方式保存了描述符表的基地址和表的长度。
指令lgdt 和sgdt 用于访问GDTR 寄存器;指令lldt 和sldt 用于访问LDTR 寄存器。
lgdt 使用的是内存中一个6 字节操作数来加载GDTR 寄存器的。
头两个字节代表描述符表的长度,后4 个字节是描述符表的基地址。
然而请注意,访问LDTR 寄存器的指令lldt 所使用的操作数却是一个2 字节的操作数,表示全局描述符表GDT 中一个描述符项的选择符。
该选择符所对应的GDT 表中的描述符项应该对应一个局部描述符表。
选择符的含义见下面说明。
31 23 15 7 0基地址(BASE) 2表限长(LIMIT) 0选择符(Selectors)逻辑地址的选择符部分是用于指定一描述符的,它是通过指定一描述符表并且索引其中的一个描述符项完成的。
下图示出了选择符的格式。
各字段的含义为:索引值(Index):用于选择指定描述符表中8192 个描述符中的一个。
处理器将该索引值乘上8(描述符的字节长度),并加上描述符表的基地址即可访问表中指定的段描述符。
表指示器(Table Indicator - TI):指定选择符所引用的描述符表。
值为0 表示指定GDT 表,值为1 表示指定当前的LDT 表。
请求者的特权级(Requestor's Privalege Level - RPL):用于保护机制。
15 3 2 1 0索引值(INDEX)TIRPL由于GDT 表的第一项(索引值为0)没有被使用,因此一个具有索引值0 和表指示器值也为0 的选择符GDTR(或LDTR)NN+1N+2N+3M附录468(也即指向GDT 的第一项的选择符)可以用作为一个空(null)选择符。
当一个段寄存器(不能是CS 或SS)加载了一个空选择符时,处理器并不会产生一个异常。
但是若使用这个段寄存器访问内存时就会产生一个异常。
对于初始化还未使用的段寄存器以陷入意外的引用来说,这个特性是很有用的。
段寄存器处理器将描述符中的信息保存在段寄存器中,因而可以避免在每次访问内存时查询描述符表。
每个段寄存器都有一个“可见”部分和一个“不可见”部分,见下图所示。
这些段地址寄存器的可见部分是由程序来操作的,就好象它们只是简单的16 位寄存器。
不可见部分则是由处理器来处理的。
对这些寄存器的加载操作使用的是普通程序指令,这些指令可以分为两类:1. 直接加载指令;例如,MOV,POP,LDS,LSS,LGS,LFS。
这些指令显式地引用了指定的段寄存器。
2. 隐式加载指令;例如,远调用CALL 和远跳转JMP。
这些指令隐式地引用了CS 段寄存器,并用新值加载到CS 中。
程序使用这些指令会把16 位的选择符加载到段寄存器的可见部分,而处理器则会自动地从描述符表中将一个描述符的基地址、段限长、类型以及其它信息加载到段寄存器中的不可见部分中去。
16 位可见部分隐藏部分CSSSDSESFSGS页变换(翻译)在地址变换的第二阶段,CPU 将线性地址转换为物理地址。
地址变换的这个阶段实现了基于分页的虚拟内存系统和分页级保护的基本功能。
页变化这一步是可选的,页变换仅在设置了CR0 的PG 比特位后才起作用,该比特位是在软件初始化时由操作系统设置的。
如果操作系统需要实现多个虚拟8086 任务、基于分页的保护机制或基于分页的虚拟内存,那么就一定要设置该位。
页框(帧)(Page Frame)页框是一个物理内存地址连续的4K 字节单元。
它以字节为边界,大小固定。
线性地址(Linear Address)线性地址通过指定一个页表、页表中的某一页以及该页中的偏移值,从而间接地指向对应的物理地址。
下图示出了线性地址的格式。
31 22 21 12 11 0页目录(DIR)页(PAGE)偏移值(OFFSET)下图示出了处理器将一个线性地址转换成物理地址的方法。