操作系统内核态和用户态几乎是考研试题中必考的题目,一般是一道选择题,但是在教材中对着一部分讲解的不是很全面。在复习中(包括我在内),往往面临两难的问题,一方面教材上的内容较少,另一方面网上的东西又太多,看的时候又不知所措。所在在这里给大家把这一块的知识点总结一下,希望能给大家带来一些启迪,同时也欢迎大家一起讨论。
操作系统的发展大致经历了无结构操作系统(第一代),模块化的操作系统(第二代),分层式结构(第三代),这些称为传统操作系统结构。而微内核操作系统是现代操作系统结构,他是在C/S(客户端/服务器)这种架构方式上发展起来的。传统操作系统的内容,大家只需要了解就可以了。重点在微内核操作系统。
微内核操作系统往往采用的是C/S模式,它把操作系统分为微内核和多个服务器。微内核主要用于(1)实现与硬件紧密相关的处理,(2)实现一些较基本的功能,(3)负责客户和服务器之间的通信。
内核的功能:
(1)进程(线程)管理 (进程或者线程的调度)
(2)低级存储器管理 (用户程序逻辑空间到内存空间的物理地址的变换)
(3)中断和陷入管理 (中断和陷入)
由于微内核结构的存在,那么程序就运行在两种不同的地方,内核态和用户态,内核态与用户态是操作系统的两种运行级别,跟intel cpu没有必然的联系。
内核态:当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核运行态(或简称为内核态)。其他的属于用户态。用户程序运行在用户态,操作系统运行在内核态.(操作系统内核运行在内核态,而服务器运行在用户态)。用户态不能干扰内核态.所以CPU指令就有两种,特权指令和非特权指令.不同的状态对应不同的指令。
特权指令:只能由操作系统内核部分使用,不允许用户直接使用的指令。如,I/O指令、置终端屏蔽指令、清内存、建存储保护、设置时钟指令(这几种记好,属于内核态)。 非特权指令:所有程序均可直接使用。
所以:
系统态(核心态、特态、管态):执行全部指令。
用户态(常态、目态):执行非特权指令。
用户态切换到内核态的3种方式:
a. 系统调用
这是用户态进程主动要求切换到内核态的一种方式,用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作,比如前例中fork()实际上就是执行了一个创建新进程的系统调用。而系统调用的机制其核心还是使用了操作系统为用户特别开放的一个中断来实现,例如Linux的int 80h中断。
b. 异常
当CPU在执行运行在用户态下的程序时,发生了某些事先不可知的异常,这时会触发由当前运行进程切换到处理此异常的内核相关程序中,也就转到了内核态,比如缺页异常。
c. 外围设备的中断
当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号,这时CPU会暂停执行下一条即将要执行的指令转而去执行与中断信号对应的处理程序,如果先前执行的指令是用户态下的程序,那么这个转换的过程自然也就发生了由用户态到内核态的切换。比如硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后续操作等。
前文已经提到,内核的功能:
(1)进程(线程)管理 (进程或者线程的调度)
(2)低级存储器管理 (用户程序逻辑空间到内存空间的物理地址的变换)
(3)中断和陷入管理 (中断和陷入)
具体的:
(1) I/O指令、置终端屏蔽指令、清内存、建存储保护、设置时钟指令。
(2) 中断、异常、陷入,比如缺页中断等
(3)进程(线程)管理
(4)系统调用,比如调用了设备驱动程序
(5)用户内存地址的转换(逻辑---> 物理映射)
以前考过的真题:
1、用户在程序中试图读某文件的第100个逻辑块,使用操作系统提供的()接口
A: 系统调用 B:图形用户接口 C:原语 D:键盘命令
解析:程序需要读取第100个逻辑块,这里发生了逻辑地址到物理地址的转换,必然要进入到内核态执行转换,所以必然要进入到内核态,在四个选型中,只有A系统调用才能进入到内核态。所以A入选。图形用户接口是用户接口,他是获得操作系统提供的服务一种方式,但是要想获得操作系统的服务,在底层仍然是使用的系统调用。
2、在中断发生后,进入中断处理的程序属于:()
A:用户程序 B:可能是应用程序,也可能是操作系统程序
C:操作系统程序 D:既不是是应用程序,也不是操作系统程序
解析:中断的处理是由操作系统内核来处理的,这是操作系统内核最基本的功能之一,所以只能是操作系统程序。
从这些题目中,可以看出,理解内核态和用户态的基本的概念,区分好他们不同的情景,并且掌握内核态的典型场景,就可以做好这一类的题目。
计算机系统中,通常CPU执行两种不同性质的程序:一种是操作系统内核程序;另一种是用户自编程序或系统外层的应用程序。对操作系统而言,这两种程序的作用不同,前者是后者的管理者,因此“管理程序”要执行一些特权指令,而“被管理程序”出于安全考虑不能执行这些指令。所谓特权指令,是指计算机中不允许用户直接使用的指令,如I/O指令、 置中断指令,存取用于内存保护的寄存器、送程序状态字到程序状态字寄存器等指令。操作系统在具体实现上划分了用户态(目态)和核心态(管态),以严格区分两类程序。
现代计算机几乎都是层次结构,操作系统的各项功能分别设置在不同层次上,一些与硬件关联较紧密的模块,诸如时钟管理、中断处理、设备驱动等处于最底层。其次是运行频率较髙的程序,诸如进程管理、存储器管理和设备管理等。这两部分内容构成了操作系统的内核。这部分内容的指令操作工作在核心态。 内核一般包括四个方面的内容:
时钟管理:
在计算机的各种部件中,时钟是最关键的设备。
时钟的第一功能是计时,操作系统需要通过时钟管理,向用户提供标准的系统时间。另外,通过时钟中断的管理,可以实现进程的切换。诸如,在分时操作系统中,釆用时间片轮转调度的实现;在实时系统中,按截止时间控制运行的实现;在批处理系统中,通过时钟管理来衡量一个作业的运行程度等。因此,系统管理的方方面面无不依赖于时钟。
中断机制
引入中断技术的初衷是提高多道程序运行环境中CPU的利用率,而且主要是针对外部设备的。
原语
按层次结构设计的操作系统,底层必然是一些可被调用的公用小程序,它们各自完成一个规定的操作。其特点是:
当中断或异常发生时,运行用户态的CPU会立即进入核心态,这是通过硬件实现的。
中断(Interruption),也称外中断,指来自CPU执行指令以外的事件的发生,如设备发出的I/O结束中断,表示设备输入/输出处理已经完成,希望处理机能够向设备发下一个输入 / 输出请求,同时让完成输入/输出后的程序继续运行。时钟中断,表示一个固定的时间片已到,让处理机处理计时、启动定时运行的任务等。这一类中断通常是与当前程序运行无关的事件,即它们与当前处理机运行的程序无关。
异常(Exception),也称内中断、例外或陷入(Trap),指源自CPU执行指令内部的事件,如程序的非法操作码、 地址越界、算术溢出、虚存系统的缺页以及专门的陷入指令等引起的事件。对异常的处理一般要依赖于当前程序的运行现场,而且异常不能被屏蔽,一旦出现应立即处理。关于内中断和外中断的联系与区别如下图:
所谓系统调用就是用户在程序中调用操作系统所提供的一些子功能,系统调用可以被看做特殊的公共子程序。系统中的各种共享资源都由操作系统统一掌管,因此在用户程序中,凡是与资源有关的操作(如存储分配、进行I/0传输以及管理文件等),都必须通过系统调用方式向操作系统提出服务请求,并由操作系统代为完成。通常,一个操作系统提供的系统调用命令有几十乃至上百条之多。
这些系统调用按功能大致可分为如下几类:
系统调用运行在系统的核心态。通过系统调用的方式来使用系统功能,可以保证系统的稳定性和安全性,防止用户随意更改或访问系统的数据或命令。系统调用命令是由操作系统提供的一个或多个子程序模块实现的。
操作系统的运行环境可以理解为:用户通过操作系统运行上层程序(如系统提供的命令解释程序或用户自编程序),而这个上层程序的运行依赖于操作系统的底层管理程序提供服务支持,当需要管理程序服务时,系统则通过硬件中断机制进入核心态,运行管理程序;也可能是程序运行出现异常情况,被动地需要管理程序的服务,这时就通过异常处理来进入核心态。当管理程序运行结束时,用户程序需要继续运行,则通过相应的保存的程序现场退出中断处理程序或异常处理程序,返回断点处继续执行。
由用户态转向核心态的例子:
内核在创建进程的时候,在创建task_struct的同时,会为进程创建相应的堆栈。每一个进程都有两个栈,一个用户栈,存在于用户空间;一个内核栈,存在于内核空间。当进程在用户空间运行时,CPU堆栈指针寄存器里面的内容都是用户栈地址,使用用户栈;当进程在内核空间时,CPU堆栈指针寄存器里面的内容是内核栈空间地址,使用内核栈。
当进程因为中断或者系统调用陷入到内核态时,进程所使用的堆栈也要从用户栈转到内核栈。进程陷入到内核态后,先把用户态堆栈的地址保存在内核栈之中,然后设置堆栈指针寄存器的内容为内核栈的地址,这样就完成了用户栈向内核栈的转换;当进程从内核态恢复到用户态之后时,在内核态之后的最后将保存在内核栈里面的用户栈的地址恢复到堆栈指针寄存器即可。这样就实现了用户栈和内核栈的互转。
那么,知道从内核转到用户态时,用户栈的地址是在陷入内核的时候保存在内核栈里面的,但是在陷入内核的时候,如何知道内核栈的地址?关键在进程从用户态转到内核态的时候,进程的内核栈总是空的。这是因为当进程在用户态运行时,使用的用户栈,当进程陷入到内核态时,内核保存进程在内核态运行的相关信息,但是一旦进程返回到用户态后,内核栈中保存的信息无效,会全部恢复,因此每次进程从用户态陷入内核的时候得到的内核栈都是空的。所以在进程陷入内核的时候,直接把内核栈的栈顶地址给堆栈指针寄存器就可以了。
相信很多家里有电脑的人偶尔会遇到蓝屏问题。出现这种情况的原因有很多,在这里就不再细说,总之是电脑出现了运行异常。出现bug在电脑中是经常的事情,电脑CPU每秒处理成千上万条指令或代码,经常出现错误是非常正常的事情。但是我们却并没有会经常遇到电脑无法运行的问题。原因就在于计算机有一套完整的异常处理机制。再者,当你在电脑上正在玩游戏时,忽然想要听歌,于是打开了音乐播放器,然而对于CPU来说,它正在运行着你的游戏,如何运行你的播放器呢?其实只要你打开了电脑,CPU就已经开始运行很多种系统软件了。然而我们知道,CPU在每一时刻都只能运行一条指令,也就是说单个CPU是无法同时运行多个程序的,之所以你能够正常使用计算机不至于经常出现蓝屏而且还能同时听歌和打游戏,正是依赖于中断机制。
中断机制是计算机的非常重要的运行机制,它的出现是操作系统的基础前提。在一个程序运行过程中,会占用CPU进行运算,同时这时如果有另外一个程序也需要使用CPU,这个程序就会发出中断请求,然后CPU将会保存现在所处理程序的运行状态,之后执行中断处理程序。看起来时比较简单的。
以上知识粗略的来讲,其实中断和异常是由区别的,中断为异步,异常为同步,但他们的处理机制是完全一致的。当CPU接收到了中断请求的信号,那么当前正在运行的程序状态将会被保存,只要保存在程序计数器(PC)和程序状态字寄存器(PSW)中,这两个都是CPU寄存器组中的寄存器。当程序执行完中断处理之后,将会从PC和PSW中读取数据,恢复被中断的程序继续执行,这称为恢复现场。
当CPU在执行中断程序时,此时又来了一个中断请求,那现在应该怎么办呢?前辈们早已想好了办法。中断分级,高级中断可以打断低级中断,比如说当正在执行一个低级中断,此时来了一个高级中断,那么这个高级中断请求就可以占用CPU运行,此时低级中断就会被保存,等待高级中断执行完成,那么低级中断再继续运行。如果在低级中断之上是更加低级的中断请求,那不好意思,你不够格,只能拒绝这种更加低级的请求。
自陷指令又称为访管指令,它也和中断机制密切相关。在了解这个指令之前我们先要了解另外一些东西。CPU在运行程序时可以分为两种状态:用户态(又称目态)和系统态(又称管态)。当CPU处于用户态时,它运行用户的应用程序,在系统态时,它运行操作系统的程序。而有时候当我们的应用程序需要用到系统功能时,CPU就需要转换状态,从用户态转换到系统态,完成这个转换的正是自陷指令。在程序状态字存储器(PSW)的首位保存着CPU目前的运行状态。由于修改程序状态字是特权指令,是不允许用户程序使用的,所以通过发出自陷指令,使CPU转换为系统态,并修改PSW。当系统态转换为用户态时,CPU直接修改PSW,变为用户态。自陷指令提供了应用程序使用系统功能的接口,使应用程序能够正常运行,与系统联系更加紧密。