Linux下如何从用户态切换到内核态?

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shanghx_123/article/details/83151064

首先我们得明白什么是用户态和内核态?
明白这两个概念之前,我们得知道用户空间内核空间
用户空间:指的就是用户可以操作和访问的空间,这个空间通常存放我们用户自己写的数据等等;而内核空间则是系统内核来操作的一块空间,这块空间里面存放系统内核的函数、接口等。
不管对于Linux还是Windows, 他们都具有自己用户空间和内核空间。当一个程序运行时,如果它是在用户空间下执行,我们把此时运行得程序的这种状态成为用户态,而当这段程序执行在内核的空间执行时,这种状态称为内核态
Linux严格意义上说的是一个操作系统,我们称之为“核心 "但我们一般用户是,不能直接使用kernel,而是通过kernel的“外壳“程序,也就是说shell,来于kernel沟通。
那什么是Shell?
Shell:命令行解释器(command Interpreter),它主要包含:
1.将使用者的命令翻译给核心(kernel)来处理。
2.将核心(kernel)的处理结果翻译给使用者。

那么对比Windows GUI,我们也不是直接操作Windows内核,而是通过GUI的图形接口,点击,从而完成我们的操作(比如进入D盘的操作,我们通常时双击D盘盘符,此时双击的操作就是通过GUI来将指令解析给Windows内核 ,从而完成操作)。
关于用户不能直接操作内核,其根本原因是为了对系统内核进行“保护”。这里我在系统调用说过。
明白上面的概念之后,现在的问题就是如何切换?
答案是软件中断。软件中断和我们常说的中断(硬件中断)不同之处在于,它是通过软件指令触发而并非外设引发的中断,也就是说,又是编程人员开发出的一种异常(该异常为正常的异常)。Linux操作系统一般是通过软件中断从用户态切换到内核态。

具体是怎么切换 ,我们再来详细分析下。

我们所说的用户态到内核态的切换,其实就是一个进程通过系统调用到内核的一些接口。从而实现切换。而该系统调用切换时通过软件中断来完成,该中断是程序人员自己开发出的一种正常的异常,那么在Linux下,这个异常具体就是调用int $0x80的汇编指令,这条汇编指令将产生向量为0x80的编程异常。

之所以系统调用需要借助这个中断异常来实现,是因为这个异常实际上就是通过系统门陷入内核(除了int 0x80外用户空间还可以通过int3——向量3、into——向量4 、bound——向量5等异常指令进入内核,而其他异常无法被用户空间程序利用,都是由系统使用的)。

好了,现在我们知道是先通过软件中断调用了0x80的这个编程异常,这个编程异常对应的是中断描述符表IDT中的第128项——也就是对应的系统门描述符。门描述符中含有一个预设的内核空间地址,它指向了系统调用处理程序:system_call()(别和系统调用服务程序混淆,这个程序在entry.S文件中用汇编语言编写)。走到这一步,我们应该画个图来理解。
在这里插入图片描述

现在我们就知道通过系统描述符中的内核空间来找到系统调用程序,从而进入到内核态。可很显然,所有的系统调用都会统一地转到这个地址,但Linux一共有319个系统调用都从这里进入内核后又该如何派发到它们到各自的服务程序去呢?

解决这个问题的方法很简单就是: 首先Linux为每个系统调用都进行了编号 (0—NR_syscall),同时在内核中保存了一张系统调用表 ,该表中保存了系统调用编号和其对应的服务例程,因此在系统调入通过系统门陷入内核前,需要把系统调用号一并传入内核。在x86上,这个传递动作是通过在执行int0x80前把调用号装入eax寄存器实现的。这样系统调用处理程序一旦运行,就可以从eax中得到数据,然后再去系统调用表中寻找相应服务例程了。为了方便理解,我把这些操作用图表示出来。
在这里插入图片描述

除了需要传递系统调用号以外,许多系统调用还需要传递一些参数到内核,比如sys_write(unsigned int fd, const char * buf, size_t count)调用就需要传递文件描述符fd、要写入的内容buf、以及写入字节数count等几个内容到内核。碰到这种情况,Linux会有6个寄存器可被用来传递这些参数:eax (存放系统调用号)、 ebx、ecx、edx、esi及edi来存放这些额外的参数(以字母递增的顺序)。具体做法是在system_call( )中使用SAVE_ALL宏把这些寄存器的值保存在内核态堆栈中。

做好上述工作之后于,再执行系统调用处理程序,这样就从用户态切换到内核态。

	以上均为本人理解,如有不正,欢迎评论指正。共同学习!

资料参考:http://blog.csdn.net/orange_os

猜你喜欢

转载自blog.csdn.net/shanghx_123/article/details/83151064
今日推荐