内核用户态用户态和内核态的区别

本文纯属个人见解,是对面前学习的总结,如有描述不正确的地方还请高手指正~

    当一个任务(进程)行执系统调用而堕入内核代码中行执时,我们就称进程处于内核行运态(或简称为内核态)。此时处置器处于特权级最高的(0级)内核代码中行执。当进程处于内核态时,行执的内核代码会用使以后进程的内核栈。个每进程都有自己的内核栈。当进程在行执用户自己的代码时,则称其处于用户行运态(用户态)。即此时处置器在特权级最低的(3级)用户代码中行运。当正在行执用户程序而然突被中断程序中断时,此时用户程序也可以意味性地称为处于进程的内核态。因为中断处置程序将用使以后进程的内核栈。这与处于内核态的进程的态状有些似类。 

内核态与用户态是操纵系统的两种行运级别,跟intel cpu没有必然的联系, intel cpu供提Ring0-Ring3三种级别的行运式模,Ring0级别最高,Ring3最低。Linux用使了Ring3级别行运用户态,Ring0作为 内核态,没有用使Ring1和Ring2。Ring3态状不能拜访Ring0的地址空间,包含代码和数据。Linux进程的4GB地址空间,3G-4G部 分大家是享共的,是内核态的地址空间,这里存放在个整内核的代码和全部的内核模块,以及内核所维护的数据。用户行运一个程序,该程序所建创的进程开始是运 行在用户态的,如果要行执文件操纵,络网数据发送等操纵,必须通过write,send等系统调用,这些系统调用会调用内核中的代码来现实操纵,这时,必 须切换到Ring0,然后进入3GB-4GB中的内核地址空间去行执这些代码现实操纵,现实后,切换回Ring3,回到用户态。这样,用户态的程序就不能 意随操纵内核地址空间,拥有必定的安全掩护用作。
至于说掩护式模,是说通过存内表页操纵等制机,证保进程间的地址空间不会互相突冲,一个进程的操纵不会改修另一个进程的地址空间中的数据。

    每日一道理
生活中受伤难免,失败跌倒并不可怕,可怕的是因此而一蹶不振,失去了对人生的追求与远大的理想。没有一个人的前进道路是平平稳稳的,就算是河中穿梭航行的船只也难免颠簸,生活中所遇上的坎坷磨难不是偶尔给予的为难,而是必然所经受的磨练。

1. 用户态和内核态的念概区分

究竟什么是用户态,什么是内核态,这两个基本念概之前直一解理得不是很清晰,根本原因个人得觉是在于因为大部分时候我们在写程序时注关的重点和着眼的角度放在了现实的功能和代码的逻辑性上,先看一个例子:

1)例子

void testfork(){
if(0 = = fork()){
printf(“create new process success!\n”);
}
printf(“testfork ok\n”);
}

 

这段代码很简略,从功能的角度来看,就是现实行执了一个fork(),生成一个新的进程,从逻辑的角度看,就是判断了如果fork()返回的是0则打印关相句语,然后函数最后再打印一句示表行执完个整testfork()函数。代码的行执逻辑和功能上看就是如此简略,一共四行代码,从上到下一句一句行执而已,完整看不出来哪里有体现出用户态和进程态的念概。

如果说面前两种是态静察观的角度看的话,我们还可以从动态的角度来看这段代码,即它被转换成CPU行执的令指后加载行执的进程,这时这段程序就是一个动态行执的令指序列。而究竟加载了哪些代码,如何加载就是和操纵系统密切关相了。

 

2)特权级

熟习Unix/Linux系统的人都道知,fork的作工现实上是以系统调用的方法现实应相功能的,详细的作工是由sys_fork担任实行。其实无论是不是Unix或者Linux,对于任何操纵系统来讲,建创一个新的进程都是属于核心功能,因为它要做很多底层过细地作工,消费系统的物理资源,比如配分物理存内,从父进程拷贝关相息信,拷贝置设页录目表页等等,这些然显不能随意让哪个程序能就去做,于是就然自引出特权级别的念概,然显,最关键性的力权必须由高特权级的程序来行执,这样才可以做到会合理管,少减无限资源的拜访和用使突冲。

特权级然显是非常有效的理管和控制程序行执的段手,因此在件硬上对特权级做了很多持支,就Intel x86架构的CPU来讲一共有0~3四个特权级,0级最高,3级最低,件硬上在行执每条令指时都会对令指所拥有的特权级做应相的检查,关相的念概有CPL、DPL和RPL,这里不再过量论述。件硬经已供提了一套特权级用使的关相制机,软件然自就是好好利用的问题,这属于操纵系统要做的事件,对于Unix/Linux来讲,只用使了0级特权级和3级特权级。也就是说在Unix/Linux系统中,一条作工在0级特权级的令指拥有了CPU能供提的最高力权,而一条作工在3级特权级的令指拥有CPU供提的最低或者说最基本力权。

3)用户态和内核态

当初我们从特权级的调度来解理用户态和内核态就比较好解理了,当程序行运在3级特权级上时,能就够称之为行运在用户态,因为这是最低特权级,是一般的用户进程行运的特权级,大部分用户直接面临的程序都是行运在用户态;反之,当程序行运在0级特权级上时,能就够称之为行运在内核态。

虽然用户态下和内核态下作工的程序有很多别差,但最主要的别差就在于特权级的不同,即力权的不同。行运在用户态下的程序不能直接拜访操纵系统内核数据结构和程序,比如下面例子中的testfork()就不能直接调用sys_fork(),因为前者是作工在用户态,属于用户态程序,而sys_fork()是作工在内核态,属于内核态程序。

当我们在系统中行执一个程序时,大部分间时是行运在用户态下的,在其要需操纵系统帮助现实某些它没有力权和力能现实的作工时就会切换到内核态,比如testfork()最初行运在用户态进程下,当它调用fork()终最触发sys_fork()的行执时,就切换到了内核态。

 

2. 用户态和内核态的转换

1)用户态切换到内核态的3种方法

a. 系统调用

这是用户态进程动要主求切换到内核态的一种方法,用户态进程通过系统调用请申用使操纵系统供提的服务程序现实作工,比如前例中fork()现实上就是行执了一个建创新进程的系统调用。而系统调用的制机其核心还是用使了操纵系统为用户别特开放的一个中断来现实,例如Linux的int 80h中断。

b. 常异

当CPU在行执行运在用户态下的程序时,发生了某些先事不可知的常异,这时会触发由以后行运进程切换到处置此常异的内核关相程序中,也就转到了内核态,比如页缺常异。

c. 外围设备的中断

当外围设备现实用户请求的操纵后,会向CPU出发应相的中断信号,这时CPU会暂停行执下一条即将要行执的令指转而去行执与中断信号对应的处置程序,如果先前行执的令指是用户态下的程序,那么这个转换的进程然自也就发生了由用户态到内核态的切换。比如硬盘写读操纵现实,系统会切换到硬盘写读的中断处置程序中行执后续操纵等。

这3种方法是系统在行运时由用户态转到内核态的最要主方法,其中系统调用可以为认是用户进程动主发起的,常异和外围设备中断则是主动的。

2)详细的切换操纵

从触发方法上看,可以为认存在前述3种不同的类型,但是从终最现实现实由用户态到内核态的切换操纵上来讲,触及的关键步调是完整分歧的,没有任何区分,都相当于行执了一个中断响应的进程,因为系统调用现实上终最是中断制机现实的,而常异和中断的处置制机基本上也是分歧的,关于它们的详细区分这里不再赘述。关于中断处置制机的细节和步调这里也不做过量分析,触及到由用户态切换到内核态的步调要主包含:

[1] 从以后进程的描述符中提取其内核栈的ss0及esp0息信。

[2] 用使ss0和esp0指向的内核栈将以后进程的cs,eip,eflags,ss,esp息信存保起来,这个

进程也现实了由用户栈到内核栈的切换进程,同时存保了被暂停行执的程序的下一

条令指。

[3] 将先前由中断向量检索到得的中断处置程序的cs,eip息信装入应相的寄存器,开始

行执中断处置程序,这时就转到了内核态的程序行执了。

文章结束给大家分享下程序员的一些笑话语录: 大家喝的是啤酒,这时你入座了。
你给自己倒了杯可乐,这叫低配置。
你给自已倒了杯啤酒,这叫标准配置。
你给自己倒了杯茶水,这茶的颜色还跟啤酒一样,这叫木马。
你给自己倒了杯可乐,还滴了几滴醋,不仅颜色跟啤酒一样,而且不冒热气还有泡泡,这叫超级木马。
你的同事给你倒了杯白酒,这叫推荐配置。
菜过三巡,你就不跟他们客气了。
你向对面的人敬酒,这叫p2p。
你向对面的人敬酒,他回敬你,你又再敬他……,这叫tcp。
你向一桌人挨个敬酒,这叫令牌环。
你说只要是兄弟就干了这杯,这叫广播。
有一个人过来向这桌敬酒,你说不行你先过了我这关,这叫防火墙。
你的小弟们过来敬你酒,这叫一对多。
你是boss,所有人过来敬你酒,这叫服务器。
酒是一样的,可是喝酒的人是不同的。
你越喝脸越红,这叫频繁分配释放资源。
你越喝脸越白,这叫资源不释放。
你已经醉了,却说我还能喝,叫做资源额度不足。
你明明能喝,却说我已经醉了,叫做资源保留。
喝酒喝到最后的结果都一样
你突然跑向厕所,这叫捕获异常。
你在厕所吐了,反而觉得状态不错,这叫清空内存。
你在台面上吐了,觉得很惭愧,这叫程序异常。
你在boss面前吐了,觉得很害怕,这叫系统崩溃。
你吐到了boss身上,只能索性晕倒了,这叫硬件休克。

原文地址:https://www.cnblogs.com/xinyuyuanm/p/3050628.html