用户态、内核态切换

1 用户态与内核态切换

1.1 概念

  • 用户态:ring3, 在应用程序中运行,代码没有对硬件的直接控制权限,程序通过调用系统接口来达到访问硬件和内存,在这种模式下,程序发生崩溃也是可以恢复的。
  • 内核态:ring0,完全在操作系统的内核中运行,对硬件有所有操作权限,可以执行所有cpu指令集,访问任意地址的内存,在内核模式下异常会导致整台机器停机。

1.2 用户态和内核态的区别

cpu指令集
cpu指令集有权限划分,分为了ring0到ring3,ring3只能使用常规cpu指令集,不能使用操作硬件资源的cpu指令集,比如IO读写,网卡访问,申请内存等。
用户程序想要读写io,必然会用到ring 0级别的cpu指令集,而此时cpu的指令集在ring3级别,需要切换指令集操作权限级别为ring0,cpu再执行相应的ring 0级别的cpu指令集,执行对应的内核代码,会使用到当前进程的内核栈。这里感觉执行操作系统的内核代码其实和用户代码并没有本质区别,权限不同而已。
每个进程都有两个栈,分别是用户栈和内核栈,对应用户态和内核态使用
内存空间
以linux 32位为例,寻址空间是4G,操作系统会把内存空间分配为2部分,一部分为内核空间,另一部分为用户空间,高位的1G由内核使用,低位的3G由各个进程使用,内核态可以操作整个4G的空间,用户态只能操作3G空间。

1.3 用户态和内核态的切换

用户态和内核态切换的主要开销如下:

  • 保留用户态现场(上下文、寄存器、用户栈等)
  • 用户栈切到内核栈,进入内核态
  • 额外的检查(内核代码对用户不信任)
  • 执行内核态代码
  • 复制内核态代码执行结果,回到用户态
  • 恢复用户态现场(上下文、寄存器、用户栈等)
    我们可以发现一次切换经历了用户态->内核态->用户态。

用户态切换到内核态的场景:

  • 系统调用:用户态进程主动切换到内核态的方式,用户态进程通过系统调用向操作系统申请资源完成工作,比如fork()就是创建新进程的系统调用。
  • 异常:当cpu在执行用户态进程时,发生了一些没有预知的异常,这时当前运行进程会切换到处理此异常的内核相关进程中,也就是切换到了内核态。
  • 中断: 当cpu执行用户态进程时,外围设备完成用户请求操作后,会向cpu发出中断信号,这时cpu会暂停执行即将执行的指令,转到与中断信号对应的处理程序去执行。

参考文章

# 从根上理解用户态与内核态

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容