系统篇
内核
应用和底层硬件(CPU、内存、硬盘等)的连接桥梁。
用户态和内核态
CPU和进程可以在两种态下运行。
内核态可以直接访问所有硬件资源,用户态需要通过“系统调用”陷入到内核态才能否则只能访问用户空间地址的内存(虚拟内存)。
什么时候能从用户态陷入到内核态
就两字——中断!
中断可能是由于系统调用(用户态主动陷入)、异常(缺页、除0)、外设中断(硬盘读写完成等)三种情况产生。
什么是系统调用
程序需要访问硬件资源时候,例如内存、硬盘、网卡,就会“系统调用”陷入内核。
一次系统调用会发生两次CPU上下文切换(CPU上下文指的是CPU寄存器和程序计数器)
第一次是从用户态切换到内核态,寄存器原来是用户态的指令位置需要先保存起来,然后更新成内核态指令的位置,最后跳转去内核态执行任务。
第二次是内核态切换回用户态,寄存器恢复为用户态的指令位置,回到用户态运行进程。
用户态和内核态是如何切换的
每个进程都有两个栈,用户栈和内核栈。运行在哪个态就会使用哪个栈。
态的切换最重要的就是栈的切换!
实际上就是把用户态的一些寄存器值压入到内核态栈,从内核态返回时弹栈。
什么是中断?为什么要有中断(外设中断)
这是系统用来相应硬件设备请求的一种机制,会打断正在执行的进程,然后调用内核中的中断处理程序来响应请求。这是一种异步的处理事件的机制,可以提高系统的并发能力。
那为什么要有这个中断,举个例子,点了个外卖,没有中断(外卖员给你打电话)的话,你就得一直盯着(同步)或者隔三岔五(CPU轮询)看一眼外卖进度,这太耽误事了。有中断(外卖员到了打电话),你就可以心安理得干别的事情,等外卖来了你再停下去处理外卖。
什么是硬件中断和软件中断
Intel的CPU提供了三种中断程序执行的机制,分别是:
- 中断(interrupt):点了下鼠标、敲了下键盘,这属于异步事件
- 异常(exception):CPU执行指令时发现了错误,比如除0、缺页,这属于同步事件
- INT指令:INT指令后面跟了一个数字,相当于直接告诉CPU中断号。Linux用的是INT 0x80
前两者属于硬件中断,因为是硬件(外设或者CPU)自动触发的
INT指令属于软件中断,是程序触发的
什么是硬中断和软中断
由CPU硬件实现的中断机制是硬中断,中断、异常、INT指令都是CPU实现的中断机制
由软件实现的中断机制是软中断,比如Linux实现的软中断守护进程
二者效果相同都是中断当前程序而去执行中断处理程序,处理完返回执行原程序
为什么要有软中断
主要就是让硬中断尽可能简单,提高系统响应速度。
比如网卡接受处理数据包这种会比较慢,而硬中断资源很宝贵,占着不放会影响别的硬中断相应(比如鼠标卡了)。而且中断处理程序相应中断时候,可能会临时关闭中断,意味着一个中断没处理完,别的中断都不能被处理。这不行!!!
所以Linux将中断分为上下两部分
- 上半部分用来快速处理和硬件紧密相关或者时间敏感的时期
- 下半部分用来延迟处理上半部分未完成的工作,一般由内核守护进程完成。就是解耦了,异步处理。这一部分是通过对软中断标记数组的某一个位置做一个标记,然后内核守护进程会轮询看数组哪个位置被标记为1了。按照标记位去找对应的处理程序。