`
izuoyan
  • 浏览: 9318421 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

操作系统用户态和内核态之间的切换过程

 
阅读更多

操作系统用户态和内核态之间的切换过程

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级最低,硬件上在执行每条指令时都会对指令所具有的特权级做相应的检查,相关的概念有CPLDPLRPL,这里不再过多阐述。硬件已经提供了一套特权级使用的相关机制,软件自然就是好好利用的问题,这属于操作系统要做的事情,对于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()实际上就是执行了一个创建新进程的系统调用。而系统调用的机制其核心还是使用了操作系统为用户特别开放的一个中断来实现,例如Linuxint 80h中断。

b. 异常

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

c. 外围设备的中断

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

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

2)具体的切换操作

从触发方式上看,可以认为存在前述3种不同的类型,但是从最终实际完成由用户态到内核态的切换操作上来说,涉及的关键步骤是完全一致的,没有任何区别,都相当于执行了一个中断响应的过程,因为系统调用实际上最终是中断机制实现的,而异常和中断的处理机制基本上也是一致的,关于它们的具体区别这里不再赘述。关于中断处理机制的细节和步骤这里也不做过多分析,涉及到由用户态切换到内核态的步骤主要包括:

[1] 从当前进程的描述符中提取其内核栈的ss0esp0信息。

[2] 使用ss0esp0指向的内核栈将当前进程的cs,eip,eflags,ss,esp信息保存起来,这个

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

条指令。

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

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

举个例子:

下面的图中执行了连续的两条指令: mov eax, 0x4

int 0x80

可以看到,指令mov eax, 0x4对应的cs0x7eip0x308ass0xfesp0x80320

这表明此条指令的特权级是3级,也就是说该指令是工作在用户态下的。

int 0x80即所谓的系统调用执行的软中断,此条指令执行完之后,cs变换成了0x8,eip0x1400ss变成了0x10, esp 变成了0x1ffffec。这时系统已经转入了内核态执行,而且栈也变为了内核栈。

内核态程序执行完毕时如果要从内核态返回用户态,可以通过执行指令iret来完成,指令iret会将先前压栈的进入内核态前的cs,eip,eflags,ss,esp信息从栈里弹出,加载到各个对应的寄存器中,重新开始执行用户态的程序,这个过程不再详述。

分享到:
评论

相关推荐

    操作系统实验——用户态与内核态

    通过本次实验,可以深入理解用户态与内核态之间的转换和它们在操作系统中扮演的角色,了解系统调用、中断处理和上下文切换在系统运行中的重要作用。这对于深入学习操作系统的设计原理和实现方法具有重要意义。

    linux使用eventfd进行用户态与内核态通信

    在提供的压缩包文件`interrupt_test`中,很可能包含了这样一个示例,演示了如何在用户态和内核态之间利用`eventfd`进行通信,并结合线程亲核技术来优化性能。代码可能包括了创建`eventfd`、设置线程亲核性、在内核...

    用户态和内核态的区别1

    总之,用户态和内核态的切换是操作系统保证安全和效率的重要机制。用户态程序在受限的环境中运行,需要内核态的服务时,通过系统调用、异常或中断请求内核介入。这种机制使得操作系统能够有效地管理和控制资源,同时...

    linux内核态与用户态通讯源代码

    在Linux操作系统中,内核态和用户态是两种不同的运行模式,它们之间的通信是系统设计中的关键部分。这里,我们关注的是如何通过源代码实现两者之间的通讯,具体体现在`leds_test.c`和`leds.c`这两个文件上。这些文件...

    用户态与内核态的交互实现

    在操作系统设计中,用户态与内核态是两种基本的执行模式,它们分别代表了不同的权限级别和功能范围。在Linux系统中,用户态和内核态的交互是通过特定的机制来实现的,这些机制确保了系统的安全性和效率。本篇文章将...

    哈工大操作系统-L11内核级线程1

    而内核级线程由操作系统内核直接控制,创建和销毁涉及到内核态的上下文切换。 - **调度与切换**:用户级线程的调度通常在用户空间进行,线程间的切换不涉及内核,效率较高;内核级线程的调度由内核决定,切换时需...

    Linux操作系统内核实习_operation6rz_linux操作系统内核_操作系统内核_

    Linux操作系统内核实习是针对初学者的一次深入学习体验,旨在帮助他们理解并掌握Linux操作系统的核心运作机制。本文将从以下几个方面详细阐述Linux内核的关键知识点: 1. **内核介绍**:Linux内核是Linux操作系统的...

    linux内核驱动和用户态通信代码

    - 内核驱动是Linux操作系统内核的一部分,用于与硬件设备交互。它们负责初始化和配置硬件,接收来自用户态的I/O请求,处理中断,并将结果返回给用户空间。 - 驱动通常包括设备初始化、设备读写操作、中断处理和...

    计算机操作系统实验运行用户态程序 (3).docx

    通过本次实验,学生不仅学习了用户态程序的加载和执行过程,还深入理解了操作系统如何保护系统资源,防止用户程序滥用权限,以及内核态与用户态之间的转换机制。这些知识对于理解和设计操作系统,以及编写系统级软件...

    第6章 从内核态到用户态1

    在本章中,我们将深入探讨计算机操作系统的内核态与用户态的概念,以及它们之间的转换。内核态和用户态是保护模式下特权级的两种表现形式,主要目的是为了保障系统的稳定性和安全性。 首先,我们要了解特权级的基本...

    重庆理工大学操作系统基于Linux0.11内核的实践

    在Linux0.11的环境下完成基于内核栈切换的进程切换、地址映射与共享、终端设备的控制、proc文件系统的实现中的三个及以上实验项目。 在Linux四项任务中成功完成了四项:基于内核栈切换的进程切换,终端设备的控制,...

    Linux操作系统内核.pdf

    总的来说,Linux操作系统内核是一个复杂的系统软件,它管理着计算机系统的所有硬件资源,提供了一个运行用户程序的安全、高效和可扩展的环境。Linux内核的源码是公开的,它允许并鼓励开发者参与到内核的开发与改进...

    电信设备-内核态与用户态的通信结构及通信方法.zip

    首先,内核态(Kernel Mode)是操作系统内核运行的环境,它拥有对硬件的直接访问权,可以执行所有指令,包括特权指令。内核态通常用于执行系统调用、中断处理和设备驱动等关键任务,其特点是安全性高,但执行效率...

    操作系统实验 4 基于内核栈切换的进程切换.docx

    操作系统实验 4 基于内核栈切换的进程切换 本实验报告旨在深入理解进程和进程切换的概念,综合应用进程、CPU 管理、PCB、LDT、内核栈、内核态等知识解决实际问题,并开始建立系统认识。 一、实验目的 通过本实验...

    操作系统实验报告-编译linux内核

    Linux内核是开源的操作系统内核,被广泛应用于各种设备,从超级计算机到智能手机。编译Linux内核是一项重要的实践任务,它涉及到对内核源代码的理解和定制,以便满足特定系统的需要。本实验报告详细记录了在Fedora ...

    多任务内核分析 多任务操作系统介绍

    其中,多任务操作系统更是成为了现代计算机系统的标配,它能够有效地管理多个应用程序的同时运行,极大地提高了计算机资源的利用率和用户的操作体验。 #### 一、多任务操作系统概述 多任务操作系统是一种可以同时...

    计算机操作系统实验-运行用户态程序.pdf

    - `Switch_To_Address_Space()`函数负责在内核态和用户态之间切换地址空间,确保用户进程能够访问其自己的虚拟内存空间,而不会干扰其他进程或操作系统内核。 7. **内核线程(Kernel_Thread)管理**: - `Kernel_...

    操作系统内核实验(linux)

    操作系统内核实验是深入理解操作系统工作原理的重要途径,特别是在Linux环境下,通过实践可以更好地学习其设计思想和实现机制。Linux是一种广泛使用的开源操作系统,它的内核是系统的核心部分,负责管理硬件资源、...

    Linux操作系统内核实习

    总的来说,《Linux操作系统内核实习》是一本全面且实践性强的书籍,适合对Linux内核感兴趣的初学者和专业人士。通过阅读和实践书中的内容,读者不仅可以深入了解Linux内核的工作原理,还能提升实际操作和解决问题的...

    内核态memcached模块

    内核态memcached模块是一种将缓存服务集成到操作系统内核中的实现,旨在提高缓存操作的效率和系统性能。memcached原本是一个用户空间的应用程序,用于提供分布式内存对象缓存服务,它允许应用程序快速存储和检索数据...

Global site tag (gtag.js) - Google Analytics