您的位置:首页 > 其它

<自已动手写操作系统>学习扎记之保护模式(x86)

2011-04-20 06:03 731 查看
学完这一章后,我尝试来好好总结一下,发现在很难做到,因为相关的细节牵扯比较多,一不小心就必须要到具体的实现细节,而要了解这些细节Intel 开发手册已有清晰的描述.下面以问题的方式要来记录一下自已的一些体会.

1. 为什么需要保护模式?

   这跟操作系统历史的发展密切相关,在早期,操作系统是单进程,你输入一个命令就执行一个命令,像DOS.完了等待用户续继输入.这挺浪费计算机资源,人们希望同时运行多个任务,即同时运行多个进程.多进程会引起一系列的问题,这里说一下一个基本的问题,怎么样保证一个进程不非法访问其它进程的内存.学过8086CPU的人知道,这种CPU是相当阳春白雪,通过段:偏移的方式就可以访问物理内存,如果我们在这种CPU上实现多进程,(我们假设速度足够快,内存足够大),操作系统能合理分配内存,但无法在软件层面保证一个进程非法访问其它的内存,也就是说需要硬件的支持.因此要稳定可靠的实现多进程,必须对原有的硬件体系进行改造增强, 现在我们给这个增强的硬件体系叫做保护模式.

2.保护模式增加有那些基本的硬件设施?

这里以IA-32为例,

a. 4个控制寄存器(32位)

  CR0 CPU工作方式工作方式控制,包含实模式/保护模式,启用与禁用分页机制等.

CR1 保留

CR2和CR3用于分页管理管理机制

b. 系统地址寄存器

GDTR(48位)全局描述符表寄存器, 包含全局描述符表段的基地址和段界限.

      LDTR(16位) 局部描述符寄存器 LDTR实际是一个特别的选择子,用来定位每个任务的局部描述符表

IDTR(48位) 中断描述符寄存器 包括IDT的基地址32位和段界限16位

TR (16位) 任务状态段寄存器 包含当前任务的任务状态段的选择子

 

3.保护模式的一些基本术语的解释?

a.描述符

描述符是一个数据结构,用来说明一段内存的情况,包括段的基地址,段界限,段属性(段类型,段权限等), 或 用来说明一种调用门,包括目标代码段的选择子,入口地址偏移和其它属性。

b.描述符表

实际是一个描述符数组,分为全局描述符表,局部描述符表,中断描述表

全局描述符表 表示系统最顶层的内存分配描述符表集合,通常包含内核所使用代码段,数据段,堆栈段,以及一些特别的段.

局部描述符表 每个任务私有的段描述表

中断描述符表 表示中断和异常处理的各种门的描述符表

c.调用门

     正如字面的意思,作用相当于一个"门",其实就是一个目标代码段的入口.包括目标代码的选择子和偏移地址和权限级别等其它属性.通常应用程序需要调用操作系统提供的服务,而应用程序运行在较低的特权级别,无法直接访问操作系统的服务,这就要通过调用门实现系统调用,这其中涉及到权限的检查,堆栈的切换等.

d.选择子

选择子有点类似于一个index,所不同的是还包含一个位指示是全局描述表还是局部描述表,还有2个字节表示RPL(Request Privilege Level),在保护模式下是加载到段寄存器CS,SS,DS,ES,FS,GS.选择子加描述符的设计个人感觉是又增加了一个层次,用描述符来专门记录内存的寻址信息,不再像8086那样寻址受寄存器位的影响,如果以后调整内存的寻址方式,基本上不会对其它硬件造成影响.

e.中断和异常

     中断和异常是硬件级实现的事件通知机制。中断概念跟实模式是一样的,只是实现的方式发生了变化。异常是CPU检测到指令的执行先决条件不满足(如除法指令不能除以0)或某些系统规则被违返或不满足(缺页等)发出的事件通知,CPU不是God,异外情况发生了只能向外发出通知请求处理。异常分为Faults,Traps和Aborts. Faults为可称之为“良性”的异常,意为可以correct并重新恢复程序执行。Traps 是一种特别的异常,用于设置断点或调试。Aborts是真的发生了错误,会中断程序的执行。中断和异常虽然概念不一样,但具体的实现的方式是一样的。

f.分段和分页

想像一下一本书,如果你把这本书每一页都撕下来排成一列,从第一页到最后一页整体就叫'段',每一页就叫'页',分段就是先确定一块'大'块的内存,确定的它的基地址和界限,然后再切分成更小的块相等的内存,这就是分页.切分页的方法通过二级目录,这里以4K每页为例,首先把线性地址的高10位作为Index在一级目录中得到二级目录的首地址,再把线性地址的中间10位作为Index在二级目录中得到物理地址高20位,最后和线性地址的低12位相加得到真正的物理地址。

另外,分页的另一个好处可以实现虚拟内存.

4.保护模式是如何工作的?

一旦把CR0的PE位(0)设为1,CPU就进入了保护模式.保护模式最大的改变首先是内存寻址。段寄存器退化成了一个选择子,EIP,ESP还是偏移地址,

寻址变成了首选通过选择子,在全局或局部描述符表中找到相应的描述符,描述符中有段的基地址,基地址加偏移地址得到线性地址,如果没有开启分页,

线性地址就是物理地址.如果开启了分页,就发生上面描述的情形。另外保护模式在这其中会进行大量的安全检查,下面描述。

5.保护模式的有那些"保护"?

    段级保护

访问是否超出段的范围,段类型是否正确,如你不能把数据段加载到代码段,段的权限级别检查等。

页级保护

包括权限和读写保护

    IOPL(I/O Permssion Level)

      提供I/O保护,如果当前的程序没有相应的权限,不能运行一些I/O敏感的指令,如in,out,cli,sti.

I/O许可位图

      控制当前的程序那些I/O端口可以访问。

保护模式的细节比较旁杂,要详细了解可以参看Intel开发手册三卷,要真的理解保护模式工作原理还得Review书上的源代码,最好自已动手调试一番。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐