-
2019-02-23 15:31:42更多相关内容
-
用户态与内核态之间切换详解
2021-08-29 14:00:25用户态和内核态对应着不同的值,用户态为3,内核态为0. 每个线程都对应着一个用户栈和内核栈,分别用来执行用户方法和内核方法。 用户方法就是普通的操作。 内核方法就是访问磁盘、内存分配、网卡、声卡等敏感操作。...用户空间和内核空间
用户程序有用户态和内核态两种状态。用户态就是执行在用户空间中,不能直接执行系统调用。必须先切换到内核态,也就是系统调用的相关数据信息必须存储在内核空间中,然后执行系统调用。
操作硬盘等资源属于敏感操作,为了内核安全,用户线程不能直接调用。而是采用了操作系统内核提供了系统调用接口,用户线程通过系统调用来实现文件读写。所以直接与硬盘打交道的是操作系统内核。
操作系统将线程分为了内核态和用户态,当用户线程调用了系统调用的时候,需要将线程从用户态切换到内核态。
无论是操作系统内核程序还是用户程序在运行的时候都需要申请内存来保存运行状态,调用方法信息、程序代码、数据等信息。
操作系统将内存分为内核空间和用户空间。
内核空间中主要负责 操作系统内核线程以及用户程序系统调用。
用户空间主要负责用户程序的非系统调用。
内核空间比用户空间拥有更高的操作级别,只有在内核空间中才可以调用操作硬件等核心资源。
操作系统将内存按1:3的比例分为了内核空间和用户空间,用户态的运行栈信息保存在用户空间中,内核态的运行栈信息保存在内核空间中。运行栈中保存了当前线程的运行信息,比如执行到了哪些方法,局部变量等。
当发生用户态和内核态之间的切换的时候,运行栈的信息发生了变化,对应的CPU中的寄存器信息也要发生变换。但是用户线程完成系统调用的时候,还是要切换回用户态,继续执行代码的。所以要将发生系统调用之前的用户栈的信息保存起来,也就是将寄存器中的数据保存到线程所属的某块内存区域。这就涉及到了数据的拷贝,同时用户态切换到内核态还需要安全验证等操作。所以用户态和内核态之间的切换是十分耗费资源的。
用户态切换到内核态
CPU中有一个标志字段,标志着线程的运行状态。用户态和内核态对应着不同的值,用户态为3,内核态为0.
每个线程都对应着一个用户栈和内核栈,分别用来执行用户方法和内核方法。
用户方法就是普通的操作。
内核方法就是访问磁盘、内存分配、网卡、声卡等敏感操作。当用户尝试调用内核方法的时候,就会发生用户态切换到内核态的转变。
切换流程:
1、每个线程都对应这一个TCB,TCB中有一个TSS字段,存储着线程对应的内核栈的地址,也就是内核栈的栈顶指针。2、因为从用户态切换到内核态时,首先用户态可以直接读写寄存器,用户态操作CPU,将寄存器的状态保存到对应的内存中,然后调用对应的系统函数,传入对应的用户栈的PC地址和寄存器信息,方便后续内核方法调用完毕后,恢复用户方法执行的现场。
3、将CPU的字段改为内核态,将内核段对应的代码地址写入到PC寄存器中,然后开始执行内核方法,相应的方法栈帧时保存在内核栈中。
4、当内核方法执行完毕后,会将CPU的字段改为用户态,然后利用之前写入的信息来恢复用户栈的执行。
从上述流程可以看出用户态切换到内核态的时候,会牵扯到用户态现场信息的保存以及恢复,还要进行一系列的安全检查,比较耗费资源。
-
Linux常问面试问题之——用户态与内核态、用户态访问内核态资源的方式、用户态到内核态的切换
2020-08-09 22:28:32用户态与内核态用户态与内核态1、背景2、定义3、用户态访问内核态资源的方式3.1、系统调用3.2、库函数3.3、Shell脚本4、用户态到内核态怎样切换?参考 用户态与内核态 1、背景 当我们在写程序是,凡是涉及到IO读写、...用户态与内核态
1、背景
当我们在写程序是,凡是涉及到IO读写、内存分配等硬件资源的操作时,往往不能直接操作,而是通过一种叫系统调用的过程,让程序陷入到内核态运行,然后内核态的CPU执行有关硬件资源操作指令,得到相关的硬件资源后在返回到用户态继续执行,之间还要进行一系列的数据传输。
假设没有这种内核态和用户态之分,程序随随便便就能访问硬件资源,比如说分配内存,程序能随意的读写所有的内存空间,如果程序员一不小心将不适当的内容写到了不该写的地方,就很可能导致系统崩溃。
为什么要有用户态和内核态?
由于需要限制不同的程序之间的访问能力, 防止他们获取别的程序的内存数据, 或者获取外围设备的数据, 并发送到网络, CPU划分出两个权限等级 – 用户态和内核态。
2、定义
系统调用将Linux整个体系分为用户态和内核态(或者说内核空间和用户空间),1、
内核
:本质上看是一种软件——控制计算机的硬件资源,并提供上层应用程序运行的环境。- cpu可以访问内存的所有数据,包括外围设备,例如硬盘,网卡,cpu也可以将自己从一个程序切换到另一个程序。
2、
用户态
:上层应用程序的活动空间,只能受限的访问内存,且不允许访问外围设备,占用cpu的能力被剥夺,cpu资源可以被其他程序获取。- 应用程序的执行必须依托于内核提供的资源,包括CPU资源、存储资源、I/O资源等。为了使上层应用能够访问到这些资源,内核必须为上层应用提供访问的接口:即
系统调用
。
具体说明
从这个图上可以更进一步对内核所做的事有一个“全景式”的印象。主要表现为:向下控制硬件资源,向内管理操作系统资源:包括进程的调度和管理、内存的管理、文件系统的管理、设备驱动程序的管理以及网络资源的管理,向上则向应用程序提供系统调用的接口。从整体上来看,整个操作系统分为两层:用户态和内核态,这种分层的架构极大地提高了资源管理的可扩展性和灵活性,而且方便用户对资源的调用和集中式的管理,带来一定的安全性。3、用户态访问内核态资源的方式
用户态的应用程序可以通过三种方式来访问内核态的资源:
- 1)系统调用
- 2)库函数
- 3)Shell脚本
3.1、系统调用
- 系统调用是操作系统的
最小功能单位
,根据不同的应用场景,不同的Linux发行版本提供的系统调用数量也不尽相同,大致在240-350之间。系统调用组成了用户态跟内核态交互的基本接口。- 例如:用户态想要申请一块20K大小的动态内存,就需要brk系统调用,将数据段指针向下偏移,如果用户态多处申请20K动态内存,同时又释放呢?这个内存的管理就变得非常的复杂。
我们可以把
系统调用看成是一种不能再化简的操作
(类似于原子操作,但是不同概念),有人把它比作一个汉字的一个“笔画”
,而一个“汉字”就代表一个上层应用
,因此,有时候如果要实现一个完整的汉字
(给某个变量分配内存空间),就必须调用很多的系统调用
。3.2、库函数
库函数就是屏蔽这些复杂的底层实现细节,减轻程序员的负担,从而更加关注上层的逻辑实现。它对系统调用进行封装,提供简单的基本接口给用户,这样增强了程序的灵活性,当然对于简单的接口,也可以直接使用系统调用访问资源,例如:
open(),write(),read()
等等。库函数根据不同的标准也有不同的版本,例如:glibc库,posix库等
。接着上面的系统调用继续说:
- 系统调用过多,这势必会加重程序员的负担,良好的程序设计方法是:重视上层的业务逻辑操作,而尽可能避免底层复杂的实现细节。
库函数
正是为了将程序员从复杂的细节中解脱出来而提出的一种有效方法。它实现对系统调用的封装
,将简单的业务逻辑接口呈现给用户,方便用户调用,从这个角度上看,库函数就像是组成汉字的“偏旁”。- 如
“人”,
对于复杂操作,我们借助于库函数来实现,如“仁”
。显然,这样的库函数依据不同的标准也可以有不同的实现版本,如ISO C标准库,POSIX标准库等。
- 如
3.3、Shell脚本
Shell是一个
特殊的应用程序
,俗称命令行,本质上是一个命令解释器,它下通系统调用,上通各种应用,通常充当着一种“胶水”的角色,来连接各个小功能程序,让不同程序能够以一个清晰的接口协同工作,从而增强各个程序的功能。
- Shell 就是一个
“中间商”,
它在用户和内核之间“倒卖”数据
,只是用户不知道罢了。 - Shell 本身并不是内核的一部分,它只是站在内核的基础上编写的一个应用程序,它和 QQ、迅雷、Firefox等其它软件没有什么区别。然而Shell 也有着它的特殊性,就是开机立马启动,并呈现在用户面前;用户通过 Shell 来使用Linux,不启动 Shell 的话,用户就没办法使用 Linux。
Shell 是如何连接用户和内核的?
shell 能够接收用户输入的命令,并对命令进行处理,处理完毕后再将结果反馈给用户,比如输出到显示器、写入到文件等,这就是大部分读者对 Shell 的认知。
你看,我一直都在使用 Shell,哪有使用内核哦?我也没有看到 Shell 将我和内核连接起来呀?
其实,Shell 程序本身的功能是很弱的,比如文件操作、输入输出、进程管理等都得依赖内核。我们运行一个命令,大部分情况下
Shell 都会去调用内核暴露出来的接口,这就是在使用内核
,只是这个过程被 Shell 隐藏了起来,它自己在背后默默进行,我们看不到而已。接口其实就是一个一个的函数,使用内核就是调用这些函数。这就是使用内核的全部内容了吗?嗯,是的!除了函数,你没有别的途径使用内核。
4、用户态到内核态怎样切换?
- Linux操作系统中主要采用了
0和3两个特权级
,分别对应的就是内核态
和用户态
。 - 运行于用户态的进程可以执行的操作和访问的资源都会受到极大的限制,而运行在内核态的进程则可以执行任何操作并且在资源的使用上没有限制。
- 很多程序开始时运行于用户态,但在执行的过程中,一些操作
需要在内核权限下才能执行
,这就涉及到一个从用户态切换到内核态的过程
。- 比如C函数库中的内存分配函数malloc(),它具体是使用sbrk()系统调用来分配内存,当malloc调用sbrk()的时候就涉及一次从用户态到内核态的切换,
- 类似的函数还有printf(),调用的是wirte()系统调用来输出字符串,等等。
U ——user(用户), K——kernal(内核)
从用户态到内核态切换可以通过三种方式:
系统调用
:其实系统调用本身就是中断,但是软件中断,跟硬中断不同。异常
: 当CPU正在执行运行在用户态的程序时,突然发生某些预先不可知的异常事件,这个时候就会触发从当前用户态执行的进程转向内核态执行相关的异常事件,典型的如缺页异常
。外设中断(硬中断)
:当外围设备完成用户的请求操作后,会像CPU发出中断信号,此时,CPU就会暂停执行下一条即将要执行的指令,转而去执行中断信号对应的处理程序,如果先前执行的指令是在用户态下,则自然就发生从用户态到内核态的转换。
注意:
系统调用的本质其实也是中断
,相对于外围设备的硬中断,这种中断称为软中断
,这是操作系统为用户特别开放的一种中断,如Linux int 80h
中断。- 从触发方式和效果上来看,这三种切换方式是完全一样的,都相当于是执行了一个中断响应的过程。但是从触发的对象来看,
系统调用
是进程主动请求切换
的,而异常和硬中断
则是被动的
。
参考
1、https://www.cnblogs.com/bakari/p/5520860.html
2、https://zhuanlan.zhihu.com/p/69554144
3、https://www.cnblogs.com/maxigang/p/9041080.html -
linux使用eventfd进行用户态与内核态通信
2018-12-17 16:57:00完整的linux使用eventfd进行用户态与内核态通信代码,里面还涉及linux用户态线程亲核,以及对应的内核态线程亲核问题。初学者,写了好几天,亲测,可用 -
内核态与用户态的转换
2021-04-13 18:55:30是用户与系统交互的操作接口.为它上面运行的程序提供服务. 操作系统内核 - 操作系统的核心.负责管理系统的进程.内存.设备驱动程序.文件和网络系统.一个内核不是一套完整的操作系统.如Linux. Linux操作系统 - 基于...概念
- 操作系统 - 管理计算机硬件与软件资源的软件.是用户与系统交互的操作接口.为它上面运行的程序提供服务.
- 操作系统内核 - 操作系统的核心.负责管理系统的进程.内存.设备驱动程序.文件和网络系统.一个内核不是一套完整的操作系统.如Linux.
- Linux操作系统 - 基于Linux 内核的操作系统.通常由Linux内核.shell(特殊的应用程序.提供运行其他程序的接口).文件系统和应用程序.
Linux体系结构
Linux 的运行空间 = 内核空间 + 用户空间
- 内核空间 - 存放的是整个内核代码和所有内核模块.以及内核所维护的数据.
- 用户空间 - 用户程序的代码和数据.
由上图可知.用户态的应用程序可以通过三种方式来访问内核态资源:
- shell
- 系统调用
- 公用函数库
Linux系统调用
操作系统提供给用户程序调用系统服务(硬件设备)的一组"特殊"接口.
为什么要设置系统调用:
- 把用户从底层的硬件编程中解放出来:
与具体的硬件完全隔离.用户不需要面向具体的硬件编码.降低了开发的复杂性和难度. - 极大的提高了系统的安全性:
将用户进程隔离实现内核"保护".用户进程不允许访问内核数据.也无法使用内核函数.用户访问内核的路径是事先规定好的.只能从规定位置进入内核.而不准许肆意跳入内核.有了这样的陷入内核的统一访问路径限制才能保证内核安全无误. - 使用户程序具有可移植性:
不同平台不同硬件
系统调用号与系统调用表
系统调用号:
每个系统调用被赋予一个系统调用号.与具体的系统调用相关联.且预先在系统文件中定义.用响应的宏表示.
系统调用表:
内核维护系统调用表.保存系统调用函数的起始地址.系统调用号对应系统调用在调用表中的偏移量.
如何切换
从用户态到内核态切换可以通过三种方式:
- 系统调用:用户态进程主动切换到内核态的方式.用户态进程通过系统调用申请使用操作系统的提供的程序完成操作.系统调用本身就是中断.
- 异常:当CPU在执行运行在用户态下的程序时.发生了某些事先不可知的异常.这时会触发由当前运行进程切换到处理此异常的内核相关程序中.也就转到了内核态.比如缺页异常.
- 外设中断:当外设完成用户的请求时.会向CPU发送中断信号.
-
用户态和内核态
2020-12-02 00:02:21CPU特权级:用户态和内核态从用户态进入内核态的方式系统调用异常中断用户态、内核态的具体切换过程结语 前言 在本文中,会涉及到中断,异常,系统调用等概念。在有些参考资料上,会将中断和系统调用归为异常的一类... -
用户态和内核态区别
2021-02-09 14:02:03操作系统用户态和内核态之间的切换过程 1. 用户态和内核态的概念区别 究竟什么是用户态,什么是内核态,这两个基本概念以前一直理解得不是很清楚,根本原因个人觉得是在于因为大部分时候我们在写程序时关注的... -
Linux内核态与用户态的数据通信方法
2020-07-02 22:32:18本文主要介绍了Linux内核与数据交流的几种方式 -
用户态和内核态的区别
2021-02-16 20:14:22一、操作系统需要两种CPU状态 ... 举例:控制转移 算数运算 取数指令访管指令(使用户程序从用户态陷入内核态) 三、特权级别 特权环:R0、R1、R2和R3 R0相当于内核态,R3相当于用户态; 不同级别能. -
Linux:用户态和内核态的区别?什么时候会从用户态切换到内核态?
2019-08-21 21:24:201、用户态和内核态的区别? 明白这两个概念之前,我们得知道用户空间和内核空间。 用户空间:指的就是用户可以操作和访问的空间,这个空间通常存放我们用户自己写的数据等。 内核空间:是系统内核来操作的一块... -
Linux 操作系统原理 — 内核态与用户态
2020-05-02 22:15:11文章目录目录Linux 的内核态与用户态系统调用ShellCPU 与内核态用户态和内核态的切换 Linux 的内核态与用户态 我们常说的 Linux 严格来说指代的是 Linux Kernel,泛指使用或裁剪标准 Linux Kernel 并在此基础之上... -
内核态和用户态的区别
2018-05-25 11:06:02当一个任务(进程)执行系统调用而...当进程在执行用户自己的代码时,则称其处于用户运行态(用户态)。即此时处理器在特权级最低的(3级)用户代码中运行。当正在执行用户程序而突然被中断程序中断时,此时用户程序... -
OS用户态和内核态
2020-07-13 10:39:473G-4G大部分是共享的,是内核态的地址空间。这里存放整个内核的代码和所有的内核模块以及内核所维护的数据。 2、特权级的概念: 对于任何操作系统来说,创建一个进程是核心功能。创建进程要做很多工作,会消耗很多... -
Linux 用户态与内核态的交互――netlink 篇
2009-10-16 22:44:48netlink 套接字实现的,例如iprote2网络管理工具,它与内核的交互就全部使用了netlink,著名的内核包过滤框架Netfilter在与用户空间的通读,也在最新版本中改变为netlink,无疑,它将是Linux用户态与内核态交流的... -
线程用户态和内核态
2019-05-14 13:59:52(1)用户态和内核态的概念? —>内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序 —>用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU... -
linux虚拟内存与物理内存,内核态与用户态
2020-05-23 14:51:28linux虚拟内存和物理内存 ,内核态与用户态 虚拟地址空间 Linux整体架构图 Linux虚拟内存 内存管理 分页式内存管理 分段式内存管理 段页式内存管理 Linux内核态和用户态 什么需要区分内核空间与用户空间 如何从用户... -
linux下内核态锁与用户态锁详细介绍
2018-11-14 16:47:521 内核态下锁 1.1 spinlock_t spinlock_t成为自旋锁,它用在临界区代码非常少的情况下。自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了... -
用户态和内核态切换
2020-12-22 21:30:27从用户态到内核态切换可以通过三种方式,或者说会导致从用户态切换到内核态的操作: 系统调用,这个上面已经讲解过了,在我公众号之前的文章也有讲解过。其实系统调用本身就是中断,但是软件中断,跟硬中断不同。... -
linux 32位与64位 内核态与用户态 内存区别
2021-03-09 09:40:03- 32 位系统:3G 用户态, 1G 内核态 - 64 位系统(只利用 48 bit 地址): 128T 用户态; 128T 内核态 - 用户态地址空间布局和管理 - mm_struct 中有映射页的统计信息(总页数, 锁定页数, 数据/代码/栈映射页数等)以及各... -
什么是用户态和内核态
2021-03-19 10:48:38什么是用户态和内核态 从图上我们可以看出来通过系统调用将Linux整个体系分为用户态和内核态(或者说内核空间和用户空间)。 那内核态到底是什么呢?其实从本质上说就是我们所说的内核,它是一种特殊的软件程序,... -
操作系统用户态和内核态之间的切换过程
2019-05-03 13:08:33操作系统用户态和内核态之间的切换过程 1. 用户态和内核态的概念区别 究竟什么是用户态,什么是内核态,这两个基本概念以前一直理解得不是很清楚,根本原因个人觉得是在于因为大部分时候我们在写程序时关注的... -
【java并发编程】底层原理——用户态和内核态的区别
2019-02-21 14:57:47java的线程是映射到操作系统原生线程之上的,如果要阻塞或唤醒一个线程就需要操作系统介入,需要在户态与核心态之间切换,这种切换会消耗大量的系统资源,因为用户态与内核态都有各自专用的内存空间,专用的寄存器等... -
Linux系统的内核态和用户态
2017-10-10 17:19:01如上图所示,从宏观上来看,Linux操作系统的体系架构分为用户态和内核态(或者用户空间和内核)。内核从本质上看是一种软件——控制计算机的硬件资源,并提供上层应用程序运行的环境。用户态即上层应用程序的活动... -
Windows用户态和内核态原理讲解
2019-11-20 00:27:07为了防止用户程序访问并篡改操作系统的关键部分,Windows使用了2种处理器存取模式(事实上Windows运行的处理器可以支持4种模式):用户模式和内核模式。用户程序运行在用户模式而操作系统代码(如系统服务和设备驱动... -
什么是内核态,什么是用户态,谁定义的?从段页层面解析用户态和内核态
2020-10-11 15:53:47应该学习过一段时间的人,都能唱出来,低2GB是用户空间,高2GB是内核空间,我们如果在用户空间访问内核空间数据,直接给你一个0xC0000005...而在用户态的时候就是CPL=3此时CPU处于用户态 再次提出几个问题解决... -
操作系统基础知识用户态和内核态的区别
2020-10-28 15:44:10这节课给你带来了一道非常经典的面试题目:用户态线程和内核态线程有什么区别? 这是一个组合型的问题,由很多小问题组装而成,比如: 用户态和内核态是什么? 用户级线程和内核级线程是一个怎样的对应关系? ... -
如何从用户态进入内核态
2021-11-19 17:19:281. 前置知识 1.1 GDT global (segment)descriptor table 全局段号记录表(全局段号描述符表),以数组的形式存放在内存的某个地方 该块内存的起始地址和有效设定个数放在CPU内的一... 内核态的优先级为3 用户. -
对内核,内核线程,用户线程,用户态,内核态,进程等理解
2019-01-31 15:06:06以下文章涉及到我对内核,内核线程,用户线程,用户态,内核态,进程等理解 如果有理解不对的地方,希望大神可以指出错误. 我对Linux 最近的理解,Linux内核是一个支撑软件,是操作系统的核心,负责管理所有的硬件资源,cpu,...