`
jakielong
  • 浏览: 229186 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Linux用户态和内核态

阅读更多

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

b. 异常

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

c. 外围设备的中断

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

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

2)具体的切换操作

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

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

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

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

条指令。

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

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

分享到:
评论

相关推荐

    详解Linux用户态与内核态通信的几种方式

    主要介绍了详解Linux用户态与内核态通信的几种方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    Linux下用户态和内核态内存共享的实现.pdf

    Linux下用户态和内核态内存共享的实现.pdf

    linux用户态和内核态的转换

    当一个任务(进程)执行系统调用而执行内核代码时,称进程处于内核内核态,此时处理器处于特权级最高的(0级)内核代码中执行,当进程处于内核态时,执行的内核代码会使用当前进程的内核栈,每个进程都有自己的内核栈...

    linux内核态与用户态内存共享示例

    ### Linux内核态与用户态内存共享示例详解 #### 背景介绍 在Linux系统中,进程间通信(IPC)是常见的需求之一。为了提高效率和灵活性,内核提供了一种机制来允许内核空间与用户空间共享内存区域。这种机制允许用户...

    Linux用户态与内核态交互 netlink的源码

    综上所述,Netlink是Linux系统中用户态与内核态交互的关键技术,它的源码分析有助于开发者深入理解内核与用户空间之间的通信机制,从而更好地设计和实现系统级程序。通过阅读和研究`目录下的源码,我们可以了解到...

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

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

    Linux 用户态与内核态的交互――netlink 篇

    Linux操作系统中的用户态和内核态是两个不同的执行环境,它们之间需要进行有效的通信来完成系统功能。在Linux 2.4及后续版本中,Netlink套接字成为了用户态和内核态交互的重要机制,尤其在处理中断过程与用户进程间...

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

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

    linux内核态与用户态通信-netlink实例解析

    在Linux操作系统中,内核态和用户态是两种不同的执行环境,它们之间的通信至关重要,确保了系统的稳定性和高效性。Netlink是一种内核与用户空间进行安全、灵活通信的机制,广泛应用于各种需要内核与应用程序交互的...

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

    - 在用户态和内核态通信中,mmap可以用来创建一个共享内存区域,这个区域对两者都是可见的,从而实现高效的数据交换。 4. **共享内存通信**: - 共享内存是一种进程间通信(IPC,Inter-Process Communication)的...

    Linux 用户态与内核态的交互 ---netlink篇的源码.rar

    Linux 用户态与内核态的交互 ---netlink篇的源码

    一图胜千言-Linux用户态系统态内核态结构图

    一图胜千言-Linux用户态系统态内核态结构图

    用户态和内核态的区别1

    用户态和内核态是操作系统中两个核心的概念,它们代表了程序执行的两种不同权限级别。用户态是普通应用程序运行的环境,而内核态则是操作系统核心和关键服务运行的环境。这两个状态之间的区别主要体现在权限和功能上...

    Linux内核同步机制

    Linux 内核同步机制是指内核中用于避免并发和防止竞争条件的机制。内核很容易产生竞争条件,因为同一时间可能有多个内核执行流在执行,内核的许多特性都要求能够并发地访问共享数据,这就要求有同步机制来同步各执行...

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

    在Linux系统中,用户态和内核态的交互是通过特定的机制来实现的,这些机制确保了系统的安全性和效率。本篇文章将详细探讨这一主题,同时也会提及提供的代码文件与这一主题的关系。 首先,我们要理解用户态和内核态...

    如何在Linux用户态开发驱动.docx

    此外,Linux社区一直在发展,可能会有新的用户态驱动开发技术出现,比如VFIO(Virtual Function I/O),它允许在用户空间直接控制PCI设备,提供更高的性能和安全性。因此,持续学习和交流是保持技术更新的关键。 总...

    嵌入式Linux网卡用户态驱动设计.pdf

    用户态驱动程序的设计和实现是为了提高嵌入式Linux系统的可靠性,通过将影响I/O性能的数据处理操作留在内核态全速运行,而将管理操作例如初始化和配置运行在速度相对较慢的用户态。 4. 数据处理操作和管理操作的...

    基于Linux的用户态文件系统的设计.pdf

    总之,基于Linux的用户态文件系统设计是一种创新的实现方法,它将文件系统的复杂逻辑移出内核,提高了开发效率和系统的可扩展性。这种设计思路为Linux系统的文件系统提供了更灵活的解决方案,有助于推动Linux生态的...

Global site tag (gtag.js) - Google Analytics