1、linux内核是什么时候运行的? 系统调用、异常、中断的时候 2、中断是什么?
中断是CPU处理外部突发事件的一个重要技术。它能使CPU在运行过程中对外部事件发出的中断请求及时地进行处理,处理完成后又立即返回断点,继续进行CPU原来的工作。引起中断的原因或者说发出中断请求的来源叫做中断源。
中断分成硬中断和软中断 硬中断:(一般执行时间都很短) 内部中断:指因硬件出错(如突然掉电、奇偶校验错等)或运算出错(除数为零、运算溢出、单步中断等)所引起的中断。 外部中断:一般是指由计算机外设发出的中断请求,如:键盘中断、打印机中断、定时器中断等。如果硬件需要CPU去做一些事情,那么这个硬件会使CPU中断当前正在运行的代码。而后CPU会将当前正在运行进程的当前状态放到堆栈(stack)中,以至于之后可以返回继续运行。
软中断:(处理一些耗时比较长的操作) 其实并不是真正的中断,它们只是可被调用执行的一般程序,产生软中断的进程一定是当前正在运行的进程,因此它们不会中断CPU。但是它们会中断调用代码的流程。
举一个计算机中的例子,常见的网卡接收网络包的例子。
网卡收到网络包后,会通过硬件中断通知内核有新的数据到了,于是内核就会调用对应的中断处理程序来响应该事件,这个事件的处理也是会分成上半部和下半部。
上部分要做到快速处理,所以只要把网卡的数据读到内存中,然后更新一下硬件寄存器的状态,比如把状态更新为表示数据已经读到内存中的状态值。
接着,内核会触发一个软中断,把一些处理比较耗时且复杂的事情,交给「软中断处理程序」去做,也就是中断的下半部,其主要是需要从内存中找到网络数据,再按照网络协议栈,对网络数据进行逐层解析和处理,最后把数据送给应用程序。 中断处理程序分成两部分,上半部和下半部。
- 上半部直接处理硬件请求,也就是硬中断,主要是负责耗时短的工作,特点是快速执行;
- 下半部是由内核触发,也就说软中断,主要是负责上半部未完成的工作,通常都是耗时比较长的事情,特点是延迟执行;
软中断(下半部)是以内核线程的方式执行,并且每一个 CPU 都对应一个软中断内核线程,名字通常为「ksoftirqd/CPU 编号」,比如 0 号 CPU 对应的软中断内核线程的名字是 ksoftirqd/0
软件中断是通知内核的机制的泛化名称,目的是促使系统切换到内核态去执行异常处理程序。这里的异常处理程序其实就是一种系统调用,软件中断可以当做一种异常。总之,软件中断是当前进程切换到系统调用的过程。
中断如何实现?
CPU如何接收中断号? 1、有一个设备叫做可编程中断控制器,接收能发出中断请求的硬件设备。通过接收外部发出的中断信号,中断控制器通过优选后吧中断号发给CPU, 2、异常就是CPU自己生成一个中断号。 3、int 指令 INT 指令后面跟一个数字,就相当于直接用指令的形式,告诉 CPU 一个中断号。 比如 INT 0x80,就是告诉 CPU 中断号是 0x80。Linux 内核提供的系统调用,就是用了 INT 0x80 这种指令。
CPU收到中断号后就需要找中断执行程序了,怎么找? 根据中断号去中断向量表中找到中断描述符,根据描述符找到对应中断处理程序的地址,然后执行。
中断描述符的分类: 中断描述符具体还分成好几个种类,有:
Task Gate:任务门描述符
Interrupt Gate:中断门描述符
Trap Gate:陷阱门描述符
中断门描述符和陷阱门描述符的区别仅仅是是否允许中断嵌套。
线程的数据结构 栈结构,双向链表(进程的线程都在链表上),线程的状态
进程的创建fork fork一次调用,返回两个进程,分别是父子进程,fork完的子进程中的线程只有一个。 子进程的虚拟内存空间是单独的,但是子进程的内存页面和父进程的内存页面实际上是映射的同一个物理内存页,所以实际上是共享的。 内核把这些页面都设置成了只读,如果父子进程只是读的话,不会有问题,但只要有一方尝试写入,就会触发异常,内核发现异常后再去分配一个新的页面让你们分开使用。
fork创建完子进程后,通过复制父进程的页表来共享父进程的地址空间,