本文共 1726 字,大约阅读时间需要 5 分钟。
本帖最后由 Philip85517 于 2010-10-14 21:58 编辑
这个问题,不太好分的太开吧。
首先要明确的一个简单的原则:软件的功能一定要建立在硬件支持的基础之上。可以说,软件实现的功能,是由硬件逻辑堆积封装而来的。
那么,一个操作系统,我们知道,它具有很多内核的代码、数据结构。控制着整个计算机系统的运转,例如I/O输出、内存访问等等。
现在的多进程操作系统,提供给了用户自己编程的功能,也就是让用户自己编程,自己创建进程。那么,一个问题就来了,一个进程假如需要系统的功能调用怎么办?
假如让进程来自己控制那些设备的驱动,那么,难免会有恶意的用户进程来破坏;或者说低水平的程序员控制错误。那么,这部分功能就交给操作系统来进行维护。
也就是说,在一个用户进程的运行过程中,它一直是处于用户态的。当需要系统的服务的时候,就必须借助一个途径,从当前PC运行的用户地址空间转移到内核的代码地址空间。这个怎么转移呢?一个答案就exception,一个与中断类似的过程。这时,这个中断处理函数就会去访问一个固定的地址,例如一张表,而那张表中登记了各个系统服务函数的入口地址(这个在系统起来的时候就创建好了)。这时候,在查到那个系统服务之后,这个exception处理函数就会将系统的状态提升到特权级,然后再进入那个服务函数,这时,系统就能继续通过特权级进行系统的操作了。当这个调用完成之后,就会返回到刚刚的handler exception处理函数之中,这时这个 exception handler函数再将系统的的状态降到用户态。这样,返回到刚才的用户进程代码空间之后,系统的特权级就降为用户态。这样,对于用户来说,只是进行了一个系统服务的调用。通过这个系统调用才能提升该进程运行过程中的系统特权级,然后运行完之后,再返回用户进程之前,重新被降为用户态。
过程如该图:
User Process:
instruction i 触发中断,有对应的处理函数入口 异常处理函数(会提升降低系统状态)
syscall ------> exception triggered ---> exception handler --> kenel function
user mode user mode ---> kernel mode
所以,从刚才的例子来看,进程的状态从用户态到系统态的提升,实际上靠的就是这个exception handler这个中断处理函数。对于这个函数的查找,我个人的理解是这样的:
在系统运行之后,操作系统有一个固定的中断号是对应于一个固定的处理函数,这个处理函数回去找一个对应的系统服务函数,在进入到这个系统服务函数之前,这个处理函数会去将寄存器对应的位修改为特权态。这时,转入到对应的系统调用函数,此时系统就允许具有特权态的CPU访问对应的内存地址(内核代码)。否则,系统就会报错。
这样的一个系统特权的提升,实际上是硬件设计好的一个存取的保护。可以这样讲。当前,我们的操作系统都使用的是分页机制,每个页都在页表中都占一个记录,而这个记录往往还有一个项记录该张页表是否能被用户态或者内核态访问。
简单的来说就是,cpu的PC取一条指令,该指令就是虚拟地址,然后根据该地址查到对应的页,此时,这个页的有一项会被检查,就是该页当前能否能被访问,判断的方式就是去查当前某个寄存器的某一位,看当前是否处于内核态,假如处于内核态,就会去访问,假如不行,那么硬件就会报错,说明该进程不能访问对应的页。
其实说白了,在系统中加了一个寄存器,在内存中的页表中放了一个对应位。然后再加上一些默认的硬件检查。看访问一张页面的时候这个寄存器是否被设置。就这么个过程而已。
最后再总结一个东西,具有内核态的 进程能够访问 系统的所有页 (这样,就能访问所有内核的代码,数据结构等等)。而只有用户态的进程只能访问它所具有访问权限的页。
我的理解就是这样,不过我自己总结下来看,内核态确实是反映在硬件上的。
但是关键是要看,当前的CPU是属于哪个进程的。当然了,因为所有进程都属于OS,所以,我觉着说OS处于什么态也是可以的……
个人理解,希望不要误导你们
转载地址:http://aqltx.baihongyu.com/