80386学习(二) 80386特权级保护

1、80386特权级保护介绍

  80386CPU为了给操做系统提供硬件级的可靠保护,提供了特权级保护功能。80386处于保护模式时,会改变CPU的行为方式,其中便包括开启特权级保护。实现良好的特权级保护是须要软硬件相协调的,CPU提供硬件机制的同时也须要与操做系统相配合,共同实现完善的特权级保护功能。算法

  要较为全面的理解特权级保护的工做原理,须要了解相互关联的各个机制。下面会介绍在80386特权级保护中起到关键做用的:段描述符和描述符表保护模式下的内存访问方式特权级的不一样维度特权级校验规则等内容。编程

2、段描述符和描述符表

  在8086中,为了可以让程序在内存中浮动的加载装配,经过段地址和段内偏移地址共同组成最终的物理地址。而在保护模式下,段机制依然存在,只不过为了支持特权级保护,在一个段可以被访问以前,须要先进行"登记注册"。数组

  用于登记注册一个段详细信息的数据结构被称为段描述符(Segment Descripter),固定占8个字节,64位。在一个多任务系统中会定义不少不一样的段,一个段就对应着一个段描述符,为了统一的进行管理,须要在内存中开辟一段连续的空间集中存放紧密相连的段描述符,而这一段连续的内存空间被称为描述符表。缓存

  描述符表有多种类型,如全局描述符表(Global Descripter Table GDT)、局部描述符(Local Descripter Table LDT)、和中断描述符表 (Interrupt Descriptor Table IDT)等数据结构

段描述符

  段描述符占8个字节,共64位。其结构以下图所示,上半部分是高32位、下半部分是低32位。并发

(截图自 x86汇编语言 从实模式到保护模式)性能

段基地址

  段基地址是一共32位的线性地址。被分为了物理上不连续的两段是由于以前的80286保护模式寻址是24位的,而为了和80286的兼容便只能在以前的段描述符设计上进行扩充。学习

  在没有开启页机制的状况下,这32位的段基地址就是最终的物理地址。操作系统

段界限

  段界限一共20位。被分为两段的缘由和段基地址同样,都是为了兼容以前80286的48位段描述符。段界限用于控制段的拓展范围,在访问时,段内偏移超过段界限时会引起错误。设计

  对于向上拓展的段,如数据段、代码段来讲,偏移量从0开始递增,段界限决定了段内偏移量的最大值。对于向下拓展的段,如栈段来讲,偏移量从0开始递减,段界限决定了段内偏移量的最小值。

  有了段界限这一限制,在使用访问段时,就能及时发现程序中对内存段访问的越界行为。更重要的是,段界限的限制可以防止程序越界,访问本来不属于该程序,不能被其访问的内存空间。

G位

  G位(Granularity)粒度位,用于解释段界限的含义。

  段描述符中的段界限是20位的,咋看之下一个段的最大空间彷佛最大只能是为20位即1MB,这和80386的最大寻址空间4GB可不太匹配。

  20位的段界限是80386的设计者为了兼容20位寻址空间而采起的兼容性设计,而G粒度位即是其中的关键。当G位=0时,段界限以字节为单位,段的最大界限就是(2^20)*1B=1MB;当G位=1时,段界限以4KB为单位,段的最大界限扩展为(2^20)*4KB=4GB,和80386的最大寻址范围相匹配,此时段界限最小也是4KB。

S位

  S位(Descriptor type)类型位,用于标识当前段的类型。

  当S=0时,表示当前段为系统段;当S=1时,表示当前段是一个代码段或数据段(栈段也被视为特殊的数据段)。

DPL字段

  DPL字段(Descriptor Privilege Level)表明当前段描述符的特权级,占两bit位。

  80386共支持4种特权级级别,分别是0,1,2,3。数字越小,特权级越高,0表明最高特权级,3表明最低特权级。

P位

  P位(Segment Present)段存在位,用于标识当前段是否存在于内存中。

  P=0时,表明段在内存中不存在;P=1时,表明段存在于内存之中。一般段描述符所指向的段老是位于内存中的。但有时物理内存空间紧张时,可能只是预先构造了段描述符,而没有分配使用对应的内存空间;或者有的操做系统会在内存紧张时将不经常使用的段暂时的交互到磁盘中,腾出内存给当前正在执行的程序,以实现段式虚拟内存。

  上述状况下,段描述符的P位就应该被置为0。CPU在对段描述符所指向的段进行访问时,会对P位进行校验。当发现P=0时,CPU会发出一个异常中断,操做系统应该提供对应的中断处理程序用于将对应内存段从磁盘中置换入内存中,同时将对应段描述符的P位置为1。

TYPE字段

  TYPE字段共4位,用于表示段描述符的子类型。

  (截图自 x86汇编语言 从实模式到保护模式)

  对于数据段来讲,TYPE的4位分别是X/E/W/A位,而对于代码段来讲,TYPE的4位分别是X/C/R/A位。其中X、A位的含义是相同的,而中间的两位因为数据段和代码段的性质不一样,被赋予了彻底不一样的含义。

既然都是内存段,如何判断一个段是数据段仍是代码段呢?

  事实上,一个段是数据段仍是代码段并不取决于定义时的段描述符,而取决于当前段被用于何种场景。

  若是被加载在CS代码段寄存器中,便被视为代码段;若是被加载在DS、ES、SS等数据段寄存器、栈段寄存器中,则被视为数据段。

TYPE字段各bit位介绍

  X(eXecutable)位标识当前段是否可执行。数据段老是不可执行的,所以X始终为0;代码段老是可执行的,所以X始终为1。

  A(Accessed)位标识当前段是否已被访问。在段描述符初始化时,应该被设置为0。当对应段被访问时,由CPU硬件将A位设置为1。操做系统在设计虚拟内存管理时,一般须要经过某些算法策略决定应该将哪些内存移入磁盘。段描述符中的A位能够帮助操做系统判断某一段时间内,对应段内存是否被访问过,为置换算法提供必定的依据。A位的清零操做也由操做系统来负责。

  E(Expand)位标识数据段的拓展方向。E=0表明数据段是向上,向高地址方向拓展,通常的数据段都是向上拓展的。E=1表明数据段是向下,向低地址方向拓展,这里主要指的就是栈段。由于入栈时,栈顶指针是自减的。

  W(Writeable)位标识数据段是否可写。数据段老是可读的,可是不必定可写 。W=0时,表明当前数据段不可写,若是对当前段有写入指令执行时,会引起CPU异常中断。W=1时,数据段可读可写。

  C(Confirming)位标识代码段是不是特权级依从的。C=0表示当前代码段是非依从的,意味着当前代码段只能被相同特权级的程序调用(或者门调用);C=1表示当前代码段是依从的,意味着当前代码段容许被更低特权级的程序调用。

关于特权级依从和门调用的概念,会在后面进行进一步介绍。

  R(ReadAble)位标识代码段是不是可读的。代码段老是能够执行的,但80386不容许对一个代码段进行写入(若是要对代码段中的内容进行修改,应该改用一个可写的数据段指向对应的内存空间)。同时,80386还对代码段的可读性作了限制。R=0时,表明该代码段是不可读的,寻址R=0的代码段将会引起处理器异常中断;R=1时,表明该代码段是可读的。这里的不可读,不是指CPU没法读取内存中的指令内容,而是用于限制程序软件的行为,例如在内存寻址中使用段超越前缀"CS:"来寻址访问代码段中的内容。

全局描述符表GDT

  描述符表中最核心的是全局描述符表。从名称中的全局二字可知,全局描述符表在80386CPU运行时是为整个软硬件提供服务的,只能存在一个。在进入保护模式前,须要事先定义好全局描述符表。

  为了让CPU可以在访问段的时候随时定位并读取到全局描述符表中的数据,80386提供了全局描述符表寄存器(Global Descripter Table Register GDTR)。

  GDTR是48位的,高位的32位用于存放全局描述符表的起始线性地址,低位的16位用于存放GDT的界限。对GDTR赋值的汇编命令为:lgdt  m16&32。 

  32位的起始线性地址,最大可寻址4GB,意味着理论上GDT能够被定义在内存的任意位置。因为进入保护模式前须要先定义GDT,所以GDT通常被设置在实模式下可寻址的1MB内的低地址(进入保护模式后也可从新定义GDT)。

  16位的界限值最大为64KB。因为段描述符大小为8个字节(8B),所以GDT中能够存放的段描述符的上限为2^10^8=8192个,这在多数状况下是绰绰有余的。

局部描述符表LDT

  现代的操做系统是多任务的,那么什么是任务呢?

  程序是保存在存储介质中的指令和数据的结合体,而正在执行程序的一个副本就是任务。一个程序能够有运行在内存中的多个副本,每一个副本都是一个任务。支持多任务的操做系统要让并发的多个任务和谐共处,就须要在任务之间经过一些手段令不一样任务间彼此隔离。通常状况下,不一样任务之间的内存是不互通的,每一个任务都有本身的内存空间,一个任务不能随意访问另外一个任务独有的内存空间。

  80386CPU的设计者建议为每一个任务分配独有的描述符表,这一描述符表被称为局部描述符表LDT。每一个任务私有的段,其段描述符不放在GDT中,而是放在LDT中。

  CPU经过能够经过GDTR寄存器来找到GDT所在的位置。一样的,80386提供了局部描述符表寄存器(Local Descripter Table Register LDTR)来追踪LDT的位置。

  和GDT不一样的是,每一个任务都有着本身的LDT。在多任务轮流执行的多任务系统中,正在执行的任务被成为当前任务,而LDTR则指向当前任务的LDT。任务切换时,LDTR中的数据会发生变化,指向新的当前任务。

3、保护模式下的内存访问方式

  前面介绍了段描述符和GDT,下面说明80386CPU在寻址时是如何与段描述符、GDT交互的。

  在8086中,段寄存器存放的是段基址。CPU进行内存寻址时,16位的段基址左移4位与16位的偏移地址相加生成最终的物理地址。而在80386中,寻址方式发生了必定的变化。

  80386中,段寄存器被扩展为了两部分。实模式下,80386段寄存器只有16位的前半部分参与工做,使用方式和8086的16位段寄存器无异,能够兼容的运行8086程序。而在保护模式下,使用段寄存器进行内存寻址的方式发生了变化。此时,前半部分16位装载的再也不是段基址,而是一种被称为段选择子的数据结构,保护模式下段寄存器的前半部分被称为段选择器;后半部分用于存储所加载的段描述符相关数据,被称为描述符高速缓冲器。

  此外,80386在8086的段寄存器CS/DS/ES/SS的基础上,还新增了两个数据段寄存器FS和GS,为复杂汇编程序的开发提供了更好的支持。

  (截图自 x86汇编语言 从实模式到保护模式)

 什么是段选择子?

  前面说到,保护模式下段寄存器中装载的再也不是段基址,而是段选择子。但CPU从本质上来讲依然是经过段基址+偏移地址进行内存寻址的,只不过在中间引入了一层段选择子的抽象,用于实现特权级保护。

  段选择子是一个16位的数据结构,由三部分组成:占高13位的段描述符索引、TI(Table Indicator)描述符表指示器以及RPL(Request Privilege Level)请求特权级。

   (截图自 x86汇编语言 从实模式到保护模式)

描述符索引

  段描述符索引用于在段描述符表中定位对应的段描述符。若是将段描述符表看做一个结构体数组,那么描述符索引就是数组的下标。

  假如段寄存器加载的是描述符表中第3个段描述符所对应的段,那当前段描述符索引的值就是0000000000010(下标从0开始)。段描述符表所能容纳的最大描述符个数是8192个,13位的描述符索引刚好可以与之一一对应。

描述符表指示器TI

   TI用于标识当前段描述符位于何种描述符表中。TI=0时,表示当前段位于GDT中;TI=1时,表示当前段位于LDT中。根据TI的不一样,在加载段选择子时,CPU将会去访问对应的段描述符表,根据描述符索引获取对应的段描述符信息,加载到段寄存器中。

  因为段选择子中并无段基址、段界限等内存寻址时的关键数据,这些数据都只在段选择子指向的段描述符中。但每次使用段寄存器寻址时,不能老是经过段描述符表获取段描述符数据,频繁的内存寻址效率过低。

  所以,80386的设计者在段寄存器中设置了描述符高速缓冲器。只有当段选择子变化时,段寄存器才须要访问一次描述符表,获取对应的段描述符数据,将其存入描述符高速缓冲器中。以后,对于当前同一段选择子的访问,即可以直接从描述符高速缓冲器中获取数据,极大的提升了CPU经过段寄存器进行内存寻址的性能。

  描述符高速缓冲器和存储器高速缓存同样,是纯硬件控制的,没法经过程序直接访问、修改其中的数据。

请求特权级RPL

  RPL请求特权级,标识着提供段选择子的程序的特权级别。RPL的做用很难单独拎出来讲明,会在接下来的段特权级访问保护机制中进行介绍。

GDT和LDT的关系

  为了更好的保护每一个任务的LDT,防止其被其它任务随意访问,须要将每一个任务的LDT视为一个须要进行特权级保护的段,将每一个任务的LDT都注册到GDT中。

  每一个任务的LDT,都有一个在GDT中的段描述符与之对应(在段描述符中S位=1的系统段)。80386CPU的LDTR被设计为16位,其中存放的是对应LDT的段选择子,当任务切换时,只需切换LDTR中的段选择子便可。

  经过段选择子寻找对应段时,若是段选择子中的TI=0,表明所要寻找的段描述符在GDT中。CPU根据GDTR中的数据,找到GDT,并按照下标计算偏移量,获取对应的段描述符。若是段选择子中的TI=1,表明所要寻找的段描述符在LDT中,CPU先根据当前LDTR中的段选择子去GDT中寻找对应的LDT段描述符,从中获取当前LDT的线性基地址。接着,再经过所请求的段选择子中的描述符索引在LDT中查找最终所需的段描述符

4、特权级的三个维度

  前面介绍了许多用于实现特权级保护的机制,如今终于能够开始说明80386到底是如何利用这些机制来完成特权级保护的。

  特权级保护从本质上来讲,是保护高特权级的内存、外设等资源不会被没有权限(低权限)的程序访问。主体结构是程序访问资源,而CPU须要在这个过程当中进行特权级的校验。

  这里引入三种不一样概念的特权级:当前特权级CPL、描述符特权级DPL、请求特权级RPL

CPL当前特权级(Current Privilege Level)

  CPL当前特权级,用于表示当前所运行程序的特权级。更进一步的说,也就是当前CS代码段寄存器中所装载段选择子的后两位所决定的特权级。

  BIOS在加载操做系统并进入保护模式时,处理器会在执行第一条指令时自动的将CPL设置为0,能够看作操做系统在进入保护模式时拥有的最高CPL是从处理器继承而来。以后便由操做系统程序负责整个计算机系统的管理,例如加载用户应用程序时,将用户程序的CPL设置为最低特权级3。应用程序虽然不但愿本身被放在最低特权级,但操做系统主导了应用程序的加载,其所使用的段描述符、LDT等都由操做系统建立和管理,应用程序只能专一于本身的业务功能,无权控制本身的CPL当前特权级。

  特权级分为4种,能够被看作几个不一样大小的同心圆,像一个个的指环,特权级0也被称为ring0。所以运行在核心处ring0特权级的操做系统程序,也被称为内核(Kernel)程序。

  (截图自 x86汇编语言 从实模式到保护模式)

特权指令

  80386CPU提供了一系列的机制实现特权级保护,如段描述符、GDT等等。全局描述符表GDT是特权级保护机制中的一个关键要素,经过指令lgdt能够进行GDT的设置。可若是本应该被高权限的操做系统管理起来的低特权级程序(CPL=3)也能执行lgdt指令的话,整个特权级保护机制就像一幢宏伟的高楼被抽离了地基,变得脆弱不堪。

  80386的设计者天然不会设计出这种百密一疏的方案。所以,在整个80386的指令集中,其中不少底层的、权限很大的指令被规定只能被最高权限的程序(例如操做系统)执行。让CPU停机也是经过指令来完成的,若是应用程序也能随意的执行停机指令,那将是很是恐怖的事情。

  只有处于最高当前特权级CPL=0的程序才有权限执行的指令,叫作特权指令。其中主要包括停机指令;加载GDT、LDT的指令;读写控制寄存器的mov指令等等。

DPL描述符特权级(Descriptor Privilege Level)

  DPL目标特权级,用于标识所指向目标的特权级。前面提到过,每一个段描述符都有DPL字段属性。DPL特权级的高低,决定了可以被位于何种特权级的程序所访问。

  CPU对内存段访问的特权级保护是在段选择子加载的时进行的。当有新的段选择子准备加载到段寄存器时,CPU会根据段寄存器的类型进行相应的校验。

代码段访问的保护机制

  对于代码段寄存器的来讲,加载新的段选择子可能意味着CPL的变化,校验比较严格,段间控制转移通常只容许发生在相同特权级的程序之间。也就是说,一个当前特权级CPL为2的程序,只能跳转到另外一个特权级DPL一样为2的代码段执行,而没法跳转到特权级DPL为0、一、3的代码段。通常程序内部相同特权级代码段间互相跳转都是没问题的,但还存在一些场景须要容许低特权级的程序去调用高特权级的代码:例如低CPL的应用程序去调用高DPL的系统调用例程。

有两种方法容许低CPL的程序跳转高DPL的代码段:

  一是将高特权级的目标代码段定义为依从的,也就是将代码段描述符中TYPE字段的C位设置为1,表明当前代码段是特权级依从的。当低特权级的程序跳转至高特权级的代码段时,CS的后两位不发生变化,CPL和调用程序保持一致。

  二是经过门来进行,门(Gate)也是一种描述符,被称为门描述符。门描述符区别于段描述符,段描述符描述的是一个段,而门描述符描述的是一段可执行的代码、一个程序或者一个任务,系统调用一般使用门描述符来实现。使用jmp far指令能够将控制经过门调用转移到高特权级代码段,可是依然不改变当前特权级CPL;使用call far指令则在将控制转移到高特权级代码段的同时,还会将当前特权级CPL提高到和目标代码段DPL一致,也就是说,一个CPL为3的应用程序,经过门调用调用到了一个DPL=0的代码段程序,则CPU将会将当前特权级CPL提高为0,和目标代码段特权级保持一致。

数据段访问的保护机制

  数据段访问的保护机制相对来讲简单一些:处于低CPL的程序没法访问高DPL的数据段。换句话说,在访问数据段前,向数据段寄存器(DS/ES/FS/GS)载入新的段选择子时,要求当前CPL必须高于或等于目标段DPL(数值上CPL <= DPL)。

  举个例子,在古代等级森严的封建制度下,皇帝能够认为是位于CPL=0的级别,普天之下莫非王土,皇帝能够在本身的国家访问任何它想要访问的领地(数据段)。但反过来位于CPL=3的平民是无法去直接访问皇宫的(DPL=0的数据段)。位于中间级别的CPL=一、2的程序就像地方诸侯,CPL=1的诸侯虽然也没法直接访问皇宫,但对于本身的寝宫(DPL=1的数据段)和平民的家(DPL=3的数据段),都是有权利访问的。

  特别的,为了不高特权级的程序因为栈空间不足而崩溃,处理器在特权级变化的时候,堆栈也会跟着发生变化。因此,向栈段寄存器SS载入新的段选择子时,要求当前CPL必须彻底等于目标的DPL(在数值上CPL = DPL)

  到了这里,看起来80386的内存保护机制彷佛已经很完善了。高特权级ring0的操做系统和低特权级ring3的应用程序彼此之间被特权级保护机制隔离开了,低特权级的应用程序不能随意的访问高特权级的操做系统内存;没有提供对应的门描述符或者依从代码段,应用程序也没法调用高特权级的程序。

  那么80386的设计者提供的请求特权级RPL做用又是什么呢?

RPL请求特权级(Request Privilege Level) 

  RPL请求特权级,表明请求者的特权级。在执行段间控制跳转指令时,须要提供目标代码段的选择子,载入CS代码段寄存器;在访问数据段时,也须要将数据段选择子装载入DS、ES等数据段寄存器中。不管是执行控制转移,仍是访问数据段,均可以看做是当前执行任务的一个请求,RPL也就是当前请求者的特权级。

  大多数状况下,请求者就是当前任务,所以CPL=RPL。谁负责提供段选择子,谁就是请求者。但在某些时刻,提供段选择子的请求者和当前任务并不相同。

  咱们知道使用call far转移指令调用操做系统提供的调用门执行系统调用时,会将CPL从应用程序的ring3提升到操做系统所处的ring0。

  假如操做系统提供了一个系统调用,用于从磁盘中读取数据,并将其写入到应用程序数据段的指定位置中(因为系统调用中可能会执行一些特权指令,或是外设被限制了访问特权级,因此经过调用门call far时会提高CPL)。这个系统调用有三个参数:磁盘的扇区号(指定从磁盘的什么位置读取),须要写入的数据段的段选择子(指定写入哪一数据段),最后一个是数据段的段内偏移地址(用于更精确的控制写入数据的段内位置)。

  这个系统调用的设计看起来还不错,能读取指定磁盘扇区的数据并写入指定数据段中,但却隐藏了一个严重问题

  若是应用程序的编写者是一名恶意的攻击者,他给出的数据段选择子参数指向的不是应用程序本身的数据段,而是操做系统的数据段选择子。虽然只有CPL=0的程序才有权限访问操做系统设置的DPL=0的内核数据段,可是因为经过call far调用门进行系统调用时,会将CPL提高为0,所以这个操做会被容许执行。这是一个很严重的漏洞,经过call far调用门实现的系统调用,模糊了CPL和事实上的请求者特权级的关系,使得只有CPL、DPL的校验机制在这种状况下显得无能为力。CPU很难区分出在段选择子的加载时,这个段选择子到底是操做系统提供的仍是恶意应用程序提供的。

  所以,80386的设计者在CPL、DPL的基础上又提供了RPL请求特权级来解决这个问题。虽然CPU不知道段选择子的提供者是谁,但操做系统是知道的。操做系统在内核中访问内存段时,请求者天然是操做系统本身;而操做系统提供系统调用为应用程序服务时,也能明确知道请求者是低特权级的应用程序。

  在上述磁盘读取系统调用的例子中,操做系统能够在系统调用的程序中修改应用程序提供的段选择子的RPL,将其设置为和应用程序匹配的低特权级后再送入段寄存器中。CPU在校验时,除了要求CPL高于或等于目标段的DPL(数值上CPL <= 目标DPL),也要求给出的段选择子中的RPL也必须高于或等于目标段的DPL(数值上RPL <= 目标DPL)。

  引入了RPL后,而且操做系统在系统调用中合理的设置了段选择子的RPL,上述漏洞就不复存在了。正常的应用程序可以访问磁盘数据,并正确的写入本身的数据段中(CPL=0 RPL=3,目标DPL=3 校验经过);但恶意的应用程序即便传入的段选择子RPL=0,也会被系统调用给重置为RPL=3,非法访问操做系统内核数据段的企图将会被CPU发现,引起异常中断(CPL=0 RPL=3,DPL=0 校验不经过)。

5、内存特权级保护校验规则

  前面的举例分析中,或多或少的介绍了几种内存访问时的特权级保护校验规则,这里系统的总结一下。内存特权级保护的规则根据内存段的性质不一样,有必定差别,分状况讨论。

代码段特权级校验规则

  非特权级依从代码段直接转移: 直接控制转移到非特权级依从的代码段时,要求当前特权级CPL、请求特权级RPL都等于目标代码段DPL(数值上CPL = 目标代码段DPL,RPL = 目标代码段DPL)。

  特权级依从代码段直接转移:直接控制转移到特权级依从的代码段时,要求当前特权级CPL、请求特权级RPL都低于或等于目标代码段DPL(数值上CPL >= 目标代码段DPL,RPL >= 目标代码段DPL)。

  门描述符特权转移:经过门描述符进行的控制转移规则较为复杂,在后续关于门描述符的博客再对门描述符控制转移的规则再进行展开介绍。

数据段特权级校验规则

  CPU容许高当前特权级的程序访问低特权级别的数据段。换句话说,低当前特权级的程序没法访问高特权级的数据段。

  即要求当前特权级CPL,请求特权级RPL都必须高于或等于目标数据段DPL(数值上CPL <= 目标数据段DPL,RPL <= 目标数据段DPL)

栈段特权级校验规则

  CPU要求任什么时候候,访问的栈段特权级必须和当前特权级CPL相一致。

  即要求当前特权级CPL,请求特权级RPL都必须等于目标栈段DPL(数值上CPL = 目标栈段DPL,RPL = 目标栈段DPL)。

6、总结

  在经过学习《x86汇编语言 从实模式到保护模式》以及有关内容的博客,掌握了必定的80386硬件及汇编知识后,我才具有了阅读、学习ucore操做系统源码的基础。虽然《x86汇编语言 从实模式到保护模式》的做者在不少地方都很体贴的站在初学者的角度来说解原理,但一方面因为本身在阅读时不够专一,另外一方面也和涉及到的知识点繁多且关系紧密有关。对我而言,单纯经过阅读学习的效果并非特别理想。 

  《暗时间》一书中提到了两个颇有价值的观点:书写是为了更好的思考、教是更好的学。在写博客的过程当中,会不自觉的反复思考并总结所写的内容,找到那些自觉得了解但事实上却理解不够深入的内容。同时假设有一个虚拟的初学者会阅读所写的博客,换位思考这个虚拟的初学者可能遇到的问题,尽量的将内容以浅显易懂的方式说清楚。固然,若是博客能帮助到和我同样,对CPU硬件、操做系统原理感兴趣的小伙伴就更好了。

  对于学习基于x86保护模式的ucore乃至流行的Linux、Windows等操做系统来讲,x86CPU的特权级保护机制是相当重要的一部分。有了硬件级别的特权级保护机制,才能实现多任务的隔离以及各类软件级别的权限控制。后续的80386学习相关博客将会包括门描述符的详细介绍以及分页机制、虚拟内存管理等相关的知识点,这些内容都是学习ucore操做系统公开课时所必须的。

  做为一个初学者,博客中若有错误或者理解不到位的地方,还请指正。

相关文章
相关标签/搜索