用户态到内核态的切换发生了什么
1.读取tr寄存器,访问TSS段
TSS段保存内核栈信息
2.从TSS段中的sp0获取进程内核栈的栈顶指针
sp:堆栈指针(Stack Pointer)寄存器,用它只可访问栈顶。
3.在内核栈中保存当前cs,ss,eip,esp寄存器的值(地址)
cs 为代码段寄存器
ss 为栈段寄存器,一般作为栈使用
eip:用来存储CPU要读取指令的地址,CPU通过EIP寄存器读取即将要执行的指令
esp:用户栈栈顶指针
4.把内核代码选择符写入CS寄存器,内核栈指针写入ESP寄存器,把内核入口点的线性地址写入EIP寄存器
此时,CPU已经切换到内核态,根据EIP中的值开始执行内核入口点的第一条指令。
中断分类
外中断
由 CPU 执行指令以外的事件引起,如 I/O 完成中断,表示设备输入/输出处理已经完成,处理器能够发送下一个输入/输出请求。此外还有时钟中断、控制台中断等。
异常
由 CPU 执行指令的内部事件引起,如非法操作码、地址越界、算术溢出等。
陷入
在用户程序中使用系统调用。
异常:异常是由当前正在执行的进程产生。异常包括很多方面,有出错(fault),有陷入(trap),也有可编程异常(programmable exception)。
出错(fault)和陷入(trap)最重要的一点区别是他们发生时所保存的EIP值的不同。出错(fault)保存的EIP指向触发异常的那条指令;而陷入(trap)保存的EIP指向触发异常的那条指令的下一条指令。因此,当从异常返回时,出错(fault)会重新执行那条指令;而陷入(trap)就不会重新执行。这一点实际上也是相当重要的,比如我们熟悉的缺页异常(page fault),由于是fault,所以当缺页异常处理完成之后,还会去尝试重新执行那条触发异常的指令(那时多半情况是不再缺页)。陷入的最主要的应用是在调试中,被调试的进程遇到你设置的断点,会停下来等待你的处理,等到你让其重新执行了,它当然不会再去执行已经执行过的断点指令。
软中断和硬中断
硬中断:
1. 硬中断是由硬件产生的,比如,像磁盘,网卡,键盘,时钟等。每个设备或设备集都有它自己的IRQ(中断请求)。基于IRQ,CPU可以将相应的请求分发到对应的硬件驱动上(注:硬件驱动通常是内核中的一个子程序,而不是一个独立的进程)。
2. 处理中断的驱动是需要运行在CPU上的,因此,当中断产生的时候,CPU会中断当前正在运行的任务,来处理中断。在有多核心的系统上,一个中断通常只能中断一颗CPU(也有一种特殊的情况,就是在大型主机上是有硬件通道的,它可以在没有主CPU的支持下,可以同时处理多个中断。)。
3. 硬中断可以直接中断CPU。它会引起内核中相关的代码被触发。对于那些需要花费一些时间去处理的进程,中断代码本身也可以被其他的硬中断中断。
4. 对于时钟中断,内核调度代码会将当前正在运行的进程挂起,从而让其他的进程来运行。它的存在是为了让调度代码(或称为调度器)可以调度多任务。
原文地址:https://www.cnblogs.com/lxy-xf/p/11431495.html