中断、异常和系统调用
文章平均质量分 78
guoguangwu
这个作者很懒,什么都没留下…
展开
-
linux内核-系统调用号与跳转表
文件include/asm-i386/unistd.h为每个系统调用定义了一个唯一的编号,称为系统调用号。部分编号如下所示:#define __NR_exit 1#define __NR_fork 2#define __NR_read 3#define __NR_write 4#define __NR_open 5#define __NR_close 6#define __NR_waitpid 7#define __NR_creat 8#原创 2021-11-07 19:18:23 · 1539 阅读 · 0 评论 -
linux内核-系统调用
如果说外部中断是使CPU被动地、异步地进入系统空间的一种手段,那么系统调用就是CPU主动地、同步地进入系统空间的手段。这里所谓主动,是指CPU自愿的、事先计划好了的行为。而同步则是说,CPU(实际上是软件的设计人员)确切地知道在执行哪一条指令以后就一定会进入系统空间。相比之下,中断的发生带有很大的不可预测性。但是,尽管有着这样的区别,二者之间还是由很大的共性。这是因为,在使CPU的运行状态从用户态转入系统态,也就是从用户空间进入系统空间,这一个基本点上二者是一致的。当然,中断有可能发生在CPU已经运行在系统原创 2021-11-07 09:22:22 · 960 阅读 · 0 评论 -
linux内核-时钟中断
在所有的外部中断中,时钟中断起着特殊的作用,其作用远非单纯的计时所能相比。当然,即使是单纯的计时也已经足够重要了。别的不说,没有正确的时间关系,你用来重建内核的工具make就不能正常运行了,因为make是靠时间标记来确定是否需要重新编译以及链接的。瞌睡时钟中断的重要性还远不止于此。我们在中断的博客中看到,内核在每次中断(以及系统调用和异常)服务完毕返回用户空间之前都要检查是否需要调度,若有需要就进行进程调度。事实上,调度只有当CPU在内核中运行时才能发生。在进程的博客中,读者将会看到进程调度发生在两种情原创 2021-11-06 21:41:34 · 2952 阅读 · 0 评论 -
linux内核-页面异常的进入返回
我们在内存管理中介绍内对页面异常处理时,是从do_page_fault开始的。当时因为尚未介绍CPU的中断和异常机制,所以暂时跳过了对页面异常的响应过程,也就是从发生异常至CPU到达do_page_fault之间的那一段路程,以及do_page_fault返回之后到CPU返回到用户空间这一段路程。我们可以来补上这个缺口了。与外设中断不同,各种异常都有为其保留的专用中断向量,因此相应的初始化也是直截了当的,这一点我们已经在初始化的博客中看到了。为页面异常设置的中断门指向程序入口page_fault(见原创 2021-11-06 16:02:40 · 374 阅读 · 0 评论 -
linux内核-软中断与Bottom Half
中断服务一般都是在将中断请求关闭的条件下执行的,以避免嵌套而使控制复杂化。可是,如果关中断的时间持续太长就可能因为CPU不能及时响应其他的中断请求而使中断(请求)丢失,为此,内核允许在将具体的中断服务程序挂入中断请求队列时将SA_INTERRUPT标志置成0,使这个中断服务程序在开中断的条件下执行。然而,实际的情况往往是:若是服务的全过程关中断则扩大打击面,而全称开中断则又造成不安定因素,很难取舍。一般来说,一次中盾服务的过程常常可以分成两部分。开头的部分往往是必须在关中断条件下执行的。这样才能在不受干扰的原创 2021-11-03 23:23:40 · 758 阅读 · 0 评论 -
linux内核-中断的响应和服务
搞清了i386 CPU的中断机制和内核中有关的初始化以后,我们就可以从中断请求的发生到CPU的响应,再到中断服务程序的调用与返回,沿着CPU所经历的路线走一遍。这样,既可以弄清和理解linux内核对中断响应和服务的总体的格局和安排,还可以顺着这个过程介绍内核中的一些相关的基础设施。对此二者的了解和理解,有助于读者对整个内核的理解。这里,我们假定外设的驱动程序都已经完成了初始化,并且把相应的中断服务程序挂入到特定的中断请求队列中,系统正在用户空间正常运行(所以中断必然是开着的),并且某个外设已经产生了一次原创 2021-10-31 16:46:44 · 1014 阅读 · 0 评论 -
linux内核-中断请求队列的初始化
在前一篇博客中,我们讲到中断向量表(更确切地,应该说中段描述表)IDT有两种表项,一种是为保留专用于CPU本身的中断门,主要用于由CPU产生到的异常,如除数为0、页面错等等,以后由用户程序通过INT指令产生的中断(或称陷阱),主要用来产生系统调用(另外还有个用于debug的INT 3)。这些中断门的向量除用于系统调用的0x80外都在0x20以下。从0x20开始就是第二种表项,共224项,都是用于外设的通用中断门。这二者的区别在于通用中断门可以为多个中断源所共享,而专用中断门则是为特定的中断源所专用。由于原创 2021-10-31 12:56:31 · 377 阅读 · 0 评论 -
linux内核-中断向量表IDT的初始化
linux内核在初始化阶段完成了对页式虚存管理的初始化以后,便调用trap_init和init_IRQ两个函数进行中断机制的初始化。其中trap_init主要是对一些系统保留的中断向量的初始化,而init_IRQ则主要用于外设的中断。函数trap_init是在include/i386/kernel/traps.c中定义的:void __init trap_init(void){#ifdef CONFIG_EISA if (isa_readl(0x0FFFD9) == 'E'+('I'<原创 2021-10-30 22:56:56 · 1350 阅读 · 0 评论 -
linux内核-X86CPU对中断的硬件支持
本博客不讨论严格意义上的中断响应全过程(比如说,怎样获得中断向量),而是着重讨论CPU在响应中断时,即在得到了中断向量以后,怎样进入相应的中断服务程序的过程。这是从操作系统的角度需要关心的问题。Intel x86 CPU支持256个不同的中断向量,这一点至今未变。可是,早期x86 CPU的中断响应机制非常原始、非常简单的。在实地址模式中,CPU把内存中从0开始的1K字节作为一个中断向量表。表中的每一个表项占四个字节,由两个字节的段地址和两个字节的位移组成。这样构成的地址便是相应中断服务程序的入口地址。这与1原创 2021-10-24 20:09:13 · 2465 阅读 · 0 评论 -
linux内核-中断、异常和系统调用
我们假定博客的读者已经具备了计算机系统结构方面的基础知识,所以本系列博客对中断以及异常(exception)处理的原理和机制不作深入的介绍。缺乏这方面基础的读者不妨先阅读一些微处理器方面的材料。不过,我们也并不要求读者对相关内容已经具备了很深入的理解。事实上,随着我们的介绍和分析,特别是随着各个情景的发展和代码的阅读,读者自会逐步地加深理解。先简要提一下,中断有两种,一种是由CPU外部产生的,另一种是由CPU本身在执行程序的过程中产生的。外部中断,就是通常所讲的中断(interrupt)。对于执行中原创 2021-10-24 17:24:36 · 190 阅读 · 0 评论