【操作系统】什么是用户态和内核态?用户态和内核态是如何切换的?

news2024/12/24 22:06:40

【操作系统】什么是用户态和内核态?用户态和内核态是如何切换的?

参考资料:

用户态到内核态切换

什么是用户态和内核态?

「操作系统」什么是用户态和内核态?为什么要区分

一、什么是用户态和内核态?

1.1、概述

用户态和内核态是操作系统的两种运行状态。

  • 内核态:处于内核态的 CPU 可以访问任意的数据,包括外围设备,比如网卡、硬盘等,处于内核态的 CPU 可以从一个程序切换到另外一个程序,并且占用 CPU 不会发生抢占情况,一般处于特权级 0 的状态我们称之为内核态。

  • 用户态:处于用户态的 CPU 只能访问受限资源,不能直接访问内存等硬件设备,不能直接访问内存等硬件设备,必须通过「系统调用」陷入到内核中,才能访问这些特权资源。

1.2、为什么要区分用户态和内核态?

在 CPU 的所有指令中,有一些指令是非常危险的,如果错用,将导致整个系统崩溃,比如:清空内存,修改时钟等。如果所有的程序代码都能够直接使用这些指令,那么很有可能我们的系统一天将会死 n 次。

所以,CPU将指令分为 特权指令非特权指令 ,对于较为危险的指令,只允许操作系统本身及其相关模块进行调用,普通的、用户自行编写的应用程序只能使用那些不会造成危险的指令。

基于安全的考虑,CPU 提供了特权分级机制,把区域分成了四个 Ring,越往里权限越高,越往外权限越低。

image-20230605002339747

操作系统根据 CPU 的特权分级机制,把进程的运行空间分为「内核空间」和「用户空间」,分别对应着上图中, CPU 特权等级的 Ring 0 和 Ring 3。

二、什么时候会从用户态陷入内核态?

有三种方式程序会从用户态陷入内核态:

  • 系统调用:这是用户态进程主动要求切换到内核态的一种方式,用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作。
  • 异常:当CPU在执行运行在用户态下的程序时,发生了某些事先不可知的异常,这时会触发由当前运行进程切换到处理此异常的内核相关程序中,也就转到了内核态,比如缺页异常。
  • 外围设备的中断:当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号,这时CPU会暂停执行下一条即将要执行的指令转而去执行与中断信号对应的处理程序,如果先前执行的指令是用户态下的程序,那么这个转换的过程自然也就发生了由用户态到内核态的切换。比如硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后续操作等。

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

三、什么是系统调用?过程是怎么样的?

当程序需要访问硬件资源的时候,比如内存、硬盘等,就需要通过「系统调用」陷入到内核中,才能访问这些特权资源。系统调用可以理解为内核实现的函数,比如应用程序要通过网卡接收数据,会调用 Socket 的 read 函数。

image-20230605004440189

程序在执行系统调用的过程中会从用户态切换到内核态,再从内核态切换到用户态,过程如下:

image-20230605004501963

系统调用的过程

  • 从用户态到内核态:当应用程序使用系统调用时,先将系统调用名称转换为系统调用号,接着将「系统调用号」和「请求参数」放到寄存器里,然后执行中断指令(int $0x80 指令),产生一个中断,CPU 陷入到内核态。
  • 执行内核态逻辑:CPU 跳转到中断处理程序,先将当前用户态的寄存器(用户态的代码段、数据段、保存参数的寄存器)保存到内核数据结构,接着将系统调用号从寄存器里面取出来,最后根据系统调用号,在「系统调用表」中找到相应的系统调用函数进行调用,并将寄存器中保存的参数取出来,作为函数参数。
  • 从内核态到用户态:执行完系统调用后,执行中断返回指令(iret 指令),将原来用户态保存的现场恢复回来,包含代码段、指令指针寄存器等。这时候 CPU 恢复到用户态,用户态进程恢复执行。

一次系统调用过程中的,会发生两次「 CPU 上下文切换」(所谓的 CPU 上下文就是 CPU 寄存器和程序计数器):

  • 第一次 CPU 上下文切换是从用户态切换到内核态:CPU 寄存器里原来用户态的指令位置,需要先保存起来。接着,为了执行内核态代码,CPU 寄存器需要更新为内核态指令的新位置。最后才是跳转到内核态运行内核任务。
  • 第二次 CPU 上下文切换是从内核态切换到用户态: CPU 寄存器需要恢复原来保存的用户态,然后再切换到用户空间,继续运行进程。

image-20230605004817167

四、用户态和内核态是如何切换的?

Linux 系统中每个进程都有两个栈,分别是用户栈和内核栈,当应用程序运行在用户态的时候,就会使用用户栈,当应用程序运行在内核态的时候,就会使用内核栈。

内核态与用户态的相互切换,其中最重要的一个步骤就是用户栈和内核栈的切换

1、用户栈到内核栈:

  • 执行中断指令(int $0x80 指令),中断发生时,CPU 去一个特定的结构(比如 TSS)中,获取该进程的内核栈的地址信息,也就是内核栈的段选择子和栈顶指针(这两个东西是描述内核栈在内存的哪个地址空间),并分别送入 ss 寄存器和 rsp 寄存器,这时候 CPU 就指向了该进程的内核栈的栈顶位置了,这就完成了用户态到内核态的一次栈的切换。(*PS:如果不明白 ss 和 rsp 寄存器是干嘛的,可以看这篇文章:一个学渣对于stack的顿悟(1):从CPU的视角说起)
  • 然后,IP 寄存器(指令指针寄存器)跳入中断服务程序开始执行,中断服务程序会把用户态的所有寄存器压入到内核栈中,如下图,CPU 自动地将用户态栈的段选择子 ss3,和栈顶指针 rsp3 都放到内核态栈里了。这里的数字 3 代表了 CPU 特权级,内核态是 0,用户态是 3。

image-20230605004937675

2、内核栈到用户栈

  • 当中断结束时,中断服务程序会从内核栈里将 CPU 寄存器的值全部恢复,最后再执行iret指令。
  • 将 ss3/rsp3 都弹出栈,并且将这个值分别送到 ss 和 rsp 寄存器中,这时候 CPU 就指向了该进程的用户栈的栈顶位置了,这样就完成了从内核栈到用户栈的一次切换。
  • 内核栈的 ss0 和 rsp0 也会被保存到前面所说的 CPU 的一个特定的结构(比如 TSS)中,以供下次切换时使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/614261.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

案例23:基于Java宿舍管理系统设计和实现开题报告

博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…

Echarts的x轴调整间隔,可以用 xAxis数组子项的axisLabel.interval

Echarts的x轴调整间隔,可以用 xAxis数组子项的axisLabel.interval https://echarts.apache.org/zh/option.html#xAxis.axisLabel.interval xAxis.axisLabel.interval auto 默认值是’auto’ 可设置为 : number 或 Function 数字或函数 坐标轴刻度标签的显示间隔,…

逍遥自在学C语言 | for循环详解

前言 C语言中的循环结构时,for循环是最常用的一种。它允许重复执行一段代码,直到满足特定条件为止。 本文将详细介绍for循环的用法,并提供相关的可编译运行的C代码示例。 一、人物简介 第一位闪亮登场,有请今后会一直教我们C语…

生产·成本

短期生产成本 给定生产技术,管理者必须选择如何生产(即使用什么样的要素组合)使生产成本最小。 衡量成本 边际成本 长期成本与规模 长期平均成本(LAC)和长期边际成本(LMC) 规模经济 随着产…

【Web网站服务】Apache网页优化

Apache网页优化 一、网页压缩1.1网页压缩步骤 二、网页缓存三、隐藏版本信息五、Apache防盗链 一、网页压缩 在企业中,部署Apache后只采用默认的配置参数,会引发网站很多问题,换言之默认配置是针对以前较低的服务器配置的,以前的…

chatgpt赋能python:Python如何拆分list

Python如何拆分list 在Python编程中,我们经常需要对list进行拆分操作。拆分list可以帮助我们更好地处理数据,以便进一步进行分析、计算或可视化呈现。本文将介绍Python中如何拆分list,并且提供一些常用的拆分方式。 按固定大小进行拆分 我…

【AIGC】12、DINO | 针对 DETR-like 检测器的提升

文章目录 一、背景二、方法2.1 Contrastive DeNoising Training2.3 Mixed Query Selection2.4 Look Forward Twice 三、效果 论文:DINO: DETR with Improved DeNoising Anchor Boxes for End-to-End Object Detection 代码:https://github.com/IDEACVR/…

【JUC基础】15. Future模式

目录 1、前言 2、什么是Future 2.1、传统程序调用 3、JDK中的Future 3.1、Future相关API 3.2、FutureTask 3.2.1、FutureTask实现 3.2.2、FutureTask相关API 3.3、CompletableFuture 3.3.1、thenApply 3.3.2、异步任务编排之thenCompose() 3.3.3、异步任务编排之th…

南京市某高校计算机科学与技术专业性能测试与Loadrunner—考试试卷分析

XXX科技学院试卷 20 /20 学年 第 学期 课程所属部门: 课程名称: 课程编号: 考试方式:(A、B、开、闭)卷 使用班级: …

数据安全--16--数据采集阶段安全防护措施

本博客地址:https://security.blog.csdn.net/article/details/131033616 一、引子 数据安全采集阶段的防护措施主要是从三个方面来开展的,第一个是从个人数据主体采集方面,第二个是从外部机构采集方面,以上两个方面基本涵盖了数…

读改变未来的九大算法笔记05_数字签名

1. 数字签名”(Digital Signature) 1.1. 单词数字化(digital)意味着其“由数字字符串组成” 1.2. 任何数字化的东西都能被拷贝 1.3. “签名”的全部意义在于能被读取,但不能被除了作者的任何人拷贝(也就…

linux(信号产生中)理论部分

1.实际执行信号的处理动作称为信号递达 2.信号从产生到递达之间的状态,称为信号未决(Pending) 3.进程可以选择阻塞某个信号的 ----------------------------------------------------------------------------------------------------------…

【JavaSE】Java(五十一):核心要点总结

文章目录 1. String str "love"; 和 String str new String("love);一样吗?2. 如何将字符串反转3. String类的常用方法有哪些?4. new String("sn") new String("ow")会创建几个对象? 1. String str “love”; 和…

「C/C++」C/C++ Lamada表达式

✨博客主页:何曾参静谧的博客 📌文章专栏:「C/C」C/C程序设计 相关术语 Lambda表达式:是C11引入的一种函数对象,可以方便地创建匿名函数。与传统的函数不同,Lambda表达式可以在定义时直接嵌入代码&#xff…

JSON与storage

JSON JSON由来 ◼ 在目前的开发中,JSON是一种非常重要的数据格式,它并不是编程语言,而是一种可以在服务器和客户端之间传输的数据格式。 ◼ JSON的全称是JavaScript Object Notation(JavaScript对象符号)&#xff1a…

苹果震撼发布首款头显,搭配强悍Mac和iOS 17等全新产品,价值25000元!

🌷 博主 libin9iOak带您 Go to New World.✨ 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发…

随机过程与排队论(一页纸总结)

参数为 λ 的泊松过程的点间间距是相互独立的随机变量,且服从均值为 1/λ 的 指数 分布。 病人以每小时3人的泊松流到达医院,设该医院只有一个医生服务且容量为无穷,医生服务的时间服从指数分布,并且平均服务一个病人为30分钟&am…

内联函数 C/C++

代码&#xff1a; file1.c #include<stdio.h>void spam(double v); void masp(double w);inline static double square(double); double square(double x) { printf("%s %s %d\n", __FILE__, __func__, __LINE__);return x * x; } int main() {double q …

chatgpt赋能python:Python如何将图片Resize

Python如何将图片Resize 在网页设计和开发过程中&#xff0c;图片大小和质量对于网站性能和用户体验至关重要。网站图片过大会影响页面加载时间&#xff0c;降低用户体验&#xff1b;同时&#xff0c;过小的图片也会影响网站排名&#xff0c;因为搜索引擎的排名算法很重视网站…

chatgpt赋能python:Python如何循环运行程序

Python如何循环运行程序 Python是一种强大的动态语言&#xff0c;具备灵活性和易用性。在编写Python程序时&#xff0c;一个常见的需求是循环运行程序&#xff0c;特别是需要定期执行一些任务的情况下。 本文将介绍如何在Python中实现循环运行程序&#xff0c;并提供一些例子…