Linux 系统中, 用户态到内核态切换的过程中发生了什么?

在Linux0.11系统中,所有中断服务程序都属于内核代码。

若中断时,进程在执行用户态的代码,该中断会引起CPU特权级从3级到0级的切换,此时CPU会进行堆栈的切换,CPU会从当前任务的TSS中取到新堆栈的段选择符和偏移值;CPU首先会把原用户态的堆栈指针ss和esp压入内核态堆栈,随后把标志寄存器eflags的内容和此次中断的返回位置cs,eip压入内核态堆栈。当中断处理函数结束后,将恢复内核栈中的数据,并继续处理被中断的进程。

若中断时,进程正在执行内核态的代码,则不需要堆栈的切换,CPU仅把eflags的内容和此次中断的返回位置cs,eip压入内核态堆栈,然后执行中断服务程序。

在这里插入图片描述

一是中断进入内核
二是异常进入内核
三是系统调用进入内核
拿x64来说,32位稍微有点不一样。

内核可以设置6个不同的内核栈,用于不同的中断,异常处理,这个是每个cpu一个的,不同cpu栈不一样。

6个是cpu提供的功能,但内核没有全部使用,调试异常,双异常,有独立的内核栈,其他异常共用一个内核栈,中断又使用另外一个内核栈,即大概使用4个不同的栈。这样设置是防止堆栈重入,比如中断处理发生异常,异常处理又发生异常,或者对中断处理代码设置断点调试。发生中断跟异常的时候,根据相应中断异常门的设置,切换内核堆栈,切换cs,权限变成0级,即内核态。rip则改成门里设置的值。

至于系统调用,现在用syscall/sysenter指令,在指令也会进入内核态,切换cs/rip,切换堆栈。这个设置有另外的寄存器设置,而不是通过门来设置。

具体到linux内核来说,每个cpu有256字节的系统调用内核栈,发生系统调用时,先进入这个小栈,然后在系统调用处理入口完成内核堆栈切换,切换到该线程所属内核栈中再进行处理。

有几种情况会导致用户态到内核态的切换:
硬件中断,进程执行过程中,好比说用户点击了什么按钮,触发了按键中断,要赶紧去处理这个中断啊,保存进程上下文,切换到中断处理流程,处理完了,恢复进程上下文,返回用户态(返回之前可能会进行进程调度,选择一个更值得运行的进程投入运行态),进程继续执行系统调用,大多数处理器以一个中断号来实现系统调用,所以处理过程和上面是一样的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值