Linux操作系统,为什么需要内核空间和用户空间?
点击上方“开源Linux”,选择“设为星标”
回复“学习”获取独家整理的学习资料!
本文以 32 位系统为例介绍内核空间(kernel space)和用户空间(user space)。
内核空间和用户空间
对 32 位操作系统而言,它的寻址空间(虚拟地址空间,或叫线性地址空间)为 4G(2的32次方)。也就是说一个进程的最大地址空间为 4G。
操作系统的核心是内核(kernel),它独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。为了保证内核的安全,现在的操作系统一般都强制用户进程不能直接操作内核。
具体的实现方式基本都是由操作系统将虚拟地址空间划分为两部分,一部分为内核空间,另一部分为用户空间。针对 Linux 操作系统而言,最高的 1G 字节(从虚拟地址 0xC0000000 到 0xFFFFFFFF)由内核使用,称为内核空间。而较低的 3G 字节(从虚拟地址 0x00000000 到 0xBFFFFFFF)由各个进程使用,称为用户空间。
对上面这段内容我们可以这样理解:「每个进程的 4G 地址空间中,最高 1G 都是一样的,即内核空间。只有剩余的 3G 才归进程自己使用。」
「换句话说就是, 最高 1G 的内核空间是被所有进程共享的!」下图描述了每个进程 4G 地址空间的分配情况(此图来自互联网):
为什么需要区分内核空间与用户空间
在 CPU 的所有指令中,有些指令是非常危险的,如果错用,将导致系统崩溃,比如清内存、设置时钟等。如果允许所有的程序都可以使用这些指令,那么系统崩溃的概率将大大增加。
所以,CPU 将指令分为特权指令和非特权指令,对于那些危险的指令,只允许操作系统及其相关模块使用,普通应用程序只能使用那些不会造成灾难的指令。
比如 Intel 的 CPU 将特权等级分为 4 个级别:Ring0~Ring3。其实 Linux 系统只使用了 Ring0 和 Ring3 两个运行级别(Windows 系统也是一样的)。
当进程运行在 Ring3 级别时被称为运行在用户态,而运行在 Ring0 级别时被称为运行在内核态。
内核态与用户态
好了我们现在需要再解释一下什么是内核态、用户态:「当进程运行在内核空间时就处于内核态,而进程运行在用户空间时则处于用户态。」
在内核态下,进程运行在内核地址空间中,此时 CPU 可以执行任何指令。运行的代码也不受任何的限制,可以自由地访问任何有效地址,也可以直接进行端口的访问。
在用户态下,进程运行在用户地址空间中,被执行的代码要受到 CPU 的诸多检查,它们只能访问映射其地址空间的页表项中规定的在用户态下可访问页面的虚拟地址,且只能对任务状态段(TSS)中 I/O 许可位图(I/O Permission Bitmap)中规定的可访问端口进行直接访问。
对于以前的 DOS 操作系统来说,是没有内核空间、用户空间以及内核态、用户态这些概念的。可以认为所有的代码都是运行在内核态的,因而用户编写的应用程序代码可以很容易的让操作系统崩溃掉。
对于 Linux 来说,通过区分内核空间和用户空间的设计,隔离了操作系统代码(操作系统的代码要比应用程序的代码健壮很多)与应用程序代码。
即便是单个应用程序出现错误也不会影响到操作系统的稳定性,这样其它的程序还可以正常的运行(Linux 可是个多任务系统啊!)。
「所以,区分内核空间和用户空间本质上是要提高操作系统的稳定性及可用性。」
如何从用户空间进入内核空间
其实所有的系统资源管理都是在内核空间中完成的。比如读写磁盘文件,分配回收内存,从网络接口读写数据等等。
我们的应用程序是无法直接进行这样的操作的。但是我们可以通过内核提供的接口来完成这样的任务。
比如应用程序要读取磁盘上的一个文件,它可以向内核发起一个 '系统调用' 告诉内核:'我要读取磁盘上的某某文件'。
其实就是通过一个特殊的指令让进程从用户态进入到内核态(到了内核空间),在内核空间中,CPU 可以执行任何的指令,当然也包括从磁盘上读取数据。具体过程是先把数据读取到内核空间中,然后再把数据拷贝到用户空间并从内核态切换到用户态。
此时应用程序已经从系统调用中返回并且拿到了想要的数据,可以开开心心的往下执行了。简单说就是应用程序把高科技的事情(从磁盘读取文件)外包给了系统内核,系统内核做这些事情既专业又高效。
对于一个进程来讲,从用户空间进入内核空间并最终返回到用户空间,这个过程是十分复杂的。举个例子,比如我们经常接触的概念 '堆栈',其实进程在内核态和用户态各有一个堆栈。
运行在用户空间时进程使用的是用户空间中的堆栈,而运行在内核空间时,进程使用的是内核空间中的堆栈。所以说,Linux 中每个进程有两个栈,分别用于用户态和内核态。
下图简明的描述了用户态与内核态之间的转换:
既然用户态的进程必须切换成内核态才能使用系统的资源,那么我们接下来就看看进程一共有多少种方式可以从用户态进入到内核态。
概括的说,有三种方式:系统调用、软中断和硬件中断
。这三种方式每一种都涉及到大量的操作系统知识,所以这里不做展开。
整体结构
接下来我们从内核空间和用户空间的角度看一看整个 Linux 系统的结构。它大体可以分为三个部分,从下往上依次为:硬件 -> 内核空间 -> 用户空间。如下图所示(此图来自互联网):
在硬件之上,内核空间中的代码控制了硬件资源的使用权,用户空间中的代码只有通过内核暴露的系统调用接口(System Call Interface)才能使用到系统中的硬件资源。其实,不光是 Linux,Windows 操作系统的设计也是大同小异。
实际上我们可以将每个处理器在任何指定时间点上的活动概括为下列三者之一:
运行于用户空间,执行用户进程。
运行于内核空间,处于进程上下文,代表某个特定的进程执行。
运行于内核空间,处于中断上下文,与任何进程无关,处理某个特定的中断。
以上三点几乎包括所有的情况,比如当 CPU 空闲时,内核就运行一个空进程,处于进程上下文,但运行在内核空间。
说明:Linux 系统的中断服务程序不在进程的上下文中执行,它们在一个与所有进程都无关的、专门的中断上下文中执行。
之所以存在一个专门的执行环境,就是为了保证中断服务程序能够在第一时间响应和处理中断请求,然后快速地退出。
总结
现代的操作系统大都通过内核空间和用户空间的设计来保护操作系统自身的安全性和稳定性。所以在我们阅读有关操作系统的资料时经常遇到内核空间、用户空间和内核态、用户态等概念,希望本文能够帮助您理解这些基本的概念。
参考:
1、https://www.cnblogs.com/Anker/p/3269106.html
2、https://blog.csdn.net/linux12121/article/details/52628941
作者:sparkdev
来源:http://www.cnblogs.com/sparkdev/
- End -
关注「开源Linux」加星标,提升IT技能
Linux操作系统,为什么需要内核空间和用户空间?的更多相关文章
- Linux 内核空间与用户空间
本文以 32 位系统为例介绍内核空间(kernel space)和用户空间(user space). 内核空间和用户空间 对 32 位操作系统而言,它的寻址空间(虚拟地址空间,或叫线性地址空间)为 4 ...
- linux内存(一) 内核空间与用户空间
来自如下网站 https://www.cnblogs.com/sparkdev/p/8410350.html 内核空间和用户空间 对 32 位操作系统而言,它的寻址空间(虚拟地址空间,或叫线性地址空间 ...
- 深入理解linux网络技术内幕读书笔记(三)--用户空间与内核的接口
Table of Contents 1 概论 1.1 procfs (/proc 文件系统) 1.1.1 编程接口 1.2 sysctl (/proc/sys目录) 1.2.1 编程接口 1.3 sy ...
- linux内核空间和用户空间详解
linux驱动程序一般工作在内核空间,但也可以工作在用户空间.下面我们将详细解析,什么是内核空间,什么是用户空间,以及如何判断他们.Linux简化了分段机制,使得虚拟地址与线性地址总是一致,因此,Li ...
- 内核空间和用户空间的分界 PAGE_OFFSET
PAGE_OFFSET 首先看看PAGE_OFFSET的功能 内存映射 | 用户空间 | 内核空间 | |——————+———— ...
- GPIO硬件资源的申请,内核空间和用户空间的数据交换,ioctl(.....),设备文件的自动创建
1.通过GPIO库函数控制LED open("/dev/myleds",...) close(fd) ----------------------------- ...
- Linux系统调用具体解释(怎样从用户空间进入内核空间)
系统调用概述 计算机系统的各种硬件资源是有限的,在现代多任务操作系统上同一时候执行的多个进程都须要訪问这些资源,为了更好的管理这些资源进程是不同意直接操作的,全部对这些资源的訪问都必须有操作系统控制. ...
- 操作系统基本概念(内核态与用户态、操作系统结构)-by sixleaves
内核态与用户态(为什么存在这种机制.程序应处于哪个状态.如何判断当前所处状态.哪些功能需要内核态.如何实现这种机制) 1.首先我们应该思考清楚为什么会有内核态和用户态?(为什么存在这种机制) 因为计算 ...
- windbg 如何再内核模式调试用户空间的程序
1:使用!process 0 0 获取用户空间的所有的进程的信息 !process 0 0 **** NT ACTIVE PROCESS DUMP **** PROCESS 80a02a60 ...
随机推荐
- 请说出作用域public,private,protected,以及不写时的区别?
这四个作用域的可见范围如下表所示.说明:如果在修饰的元素上面没有写任何访问修饰符,则表示friendly.作用域 当前类 同一package 子孙类 其他packagepublic ...
- Homebrew安装环境
p.p1 { margin: 0; font: 11px Menlo; color: rgba(0, 0, 0, 1) } span.s1 { font-variant-ligatures: no-c ...
- 什么是 Spring MVC 框架的控制器?
控制器提供一个访问应用程序的行为,此行为通常通过服务接口实现.控制器解 析用户输入并将其转换为一个由视图呈现给用户的模型.Spring 用一个非常抽象 的方式实现了一个控制层,允许用户创建多种用途的控 ...
- jsp报错问题之“使用jstl的c标签choose报错Illegal text inside "c:choose" tag问题”
一.报错 [bessky_it][ERROR][2022-03-25 17:19:07] | PLATFORM | ):[c]鍜孾/com.bessky.pss.portal/purchase/sam ...
- 《Advanced Bash-Scripting Guide》 in Chinese 高级Bash脚本编程指南》Revision 10中文版
<Advanced Bash-Scripting Guide> in Chinese <高级Bash脚本编程指南>Revision 10中文版 在线阅读链接:http://ww ...
- python爬虫---虎牙直播封面采集
代码: import requests from lxml import etree # html解析库 source = requests.get("https://www.huya.co ...
- java中异常到底有什么用?举例
异常的意义:马克-to-win:通过上面的例子,我们看出通过引入异常这种技术,即使出现不测(用户把0赋给除数),也可以让程序不崩溃,还能继续优雅 的运行.那,这种技术有用,值得学.马克-to-win: ...
- Android优化应用启动速度
一.应用的启动 启动方式 通常来说,在安卓中应用的启动方式分为两种:冷启动和热启动. 1.冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就是冷启动 ...
- 如何在jsp界面进行判断再输出不同的值
C标签的out <td> <c:if test="${nowtime eq returntime}"> <c:out value="逾期&q ...
- Blazor组件自做二 : 使用JS隔离制作手写签名组件
Blazor组件自做二 : 使用JS隔离制作手写签名组件 本文相关参考链接 JavaScript 模块中的 JavaScript 隔离 Viewer.js工程 Blazor组件自做一 : 使用JS隔离 ...