




已阅读5页,还剩52页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
深入剖析Linux中断机制中断概述【摘要】本文详解了Linux内核的中断实现机制。首先介绍了中断的一些基本概念,然后分析了面向对象的Linux中断的组织形式、三种主要数据结构及其之间的关系。随后介绍了Linux处理异常和中断的基本流程,在此基础上分析了中断处理的详细流程,包括保存现场、中断处理、中断退出时的软中断执行及中断返回时的进程切换等问题。最后介绍了中断相关的API,包括中断注册和释放、中断关闭和使能、如何编写中断ISR、共享中断、中断上下文中断状态等。【关键字】中断,异常,hw_interrupt_type,irq_desc_t,irqaction,asm_do_IRQ,软中断,进程切换,中断注册释放request_irq,free_irq,共享中断,可重入,中断上下文 1 中断概述1.1 为什么需要中断?处理器的速度跟外围硬件设备的速度往往不在一个数量级上,因此,如果内核采取让处理器向硬件发出一个请求,然后专门等待回应的办法,显然差强人意。既然硬件的响应这么慢,那么内核就应该在此期间处理其他事务,等到硬件真正完成了请求的操作之后,再回过头来对它进行处理。想要实现这种功能,轮询(polling)可能会是一种解决办法。可以让内核定期对设备的状态进行查询,然后做出相应的处理。不过这种方法很可能会让内核做不少无用功,因为无论硬件设备是正在忙碌着完成任务还是已经大功告成,轮询总会周期性地重复执行。更好的办法是由我们来提供一种机制,让硬件在需要的时候再向内核发出信号(变内核主动为硬件主动)。这就是中断机制。 1.2 中断的表示形式硬件设备生成中断的时候并不考虑与处理器的时钟同步换句话说就是中断随时可以产生。因此,内核随时可能因为新到来的中断而被打断。 从物理学的角度看,中断是一种电信号,由硬件设备生成,并直接送入中断控制器的输入引脚上。然后再由中断控制器向处理器发送相应的信号。处理器一经检测到此信号,便中断自己的当前工作转而处理中断。此后,处理器会通知操作系统已经产生中断,这样,操作系统就可以对这个中断进行适当的处理了。 不同的设备对应的中断不同,而每个中断都通过一个惟一的数字标识。因此,来自键盘的中断就有别干来自硬盘的中断,从而使得操作系统能够对中断进行区分,并知道哪个硬件设备产生了哪个中断。这样,操作系统才能给不同的中断提供不同的中断处理程序。 这些中断值通常被为中断请求(IRQ)线。通常IRQ都是一些数值量。例如在PC上,IRQ0是时钟中断,而IRQ 1是键盘中断。但并非所有的中断号都是这样严格定义的。例如,对于连接在PCI总线上的设备而言,中断是动态分配的。而在嵌入式系统中,由于中断线有限,一般外设和中断都是一一匹配的,很少有动态分配中断的。不管怎样,重点在于特定的中断总是与特定的设备相关联,并且内核要知道这些信息。 1.3 异常在操作系统中,讨论中断就不能不提及异常。广义的中断可分为同步(synchronous)中断和异步(asynchronous)中断:同步中断:是当指令执行时由 CPU 控制单元产生,之所以称为同步,是因为只有在一条指令执行完毕后 CPU 才会发出中断,而不是发生在代码指令执行期间,比如系统调用。异步中断:是指由其他硬件设备依照 CPU 时钟信号随机产生,即意味着中断能够在指令之间发生,例如键盘中断。 一般由处理器本身产生的同步中断称为异常(exception),异步中断被称为中断(interrupt)。中断可分为可屏蔽中断(Maskable interrupt)和非屏蔽中断(Nomaskable interrupt)。异常可分为故障(fault)、陷阱(trap)、终止(abort)三类。表 1:中断类别及其行为类别 原因 异步/同步 返回行为 中断 来自I/O设备的信号 异步 总是返回到下一条指令 陷阱 有意的异常 同步 总是返回到下一条指令 故障 潜在可恢复的错误 同步 返回到当前指令 终止 不可恢复的错误 同步 不会返回 在处理器执行到由于编程失误而导致的错误指令(例如被0除)的时候,或者是在执行期间出现特殊情况(例如缺页),必须靠内核来处理的时候,处理器就会产生一个异常。因为许多处理器体系结构处理异常与处理中断的方式类似,因此,内核对它们的处理也很类似。 通过软中断实现系统调用,那就是陷人内核,然后引起一种特殊的异常系统调用处理程序异常。你将会看到,中断的工作方式与之类似,其差异只在于中断是由硬件而不是软件引起的。 1.4 中断处理程序在响应一个特定中断的时候,内核会执行一个函数,该函数叫做中断处理程序(interrupt handler)或中断服务例程(interrupt service routine, ISR)。产生中断的每个设备都有一个相应的中断处理程序。 在Linux中,中断处理程序看起来就是普普通通的C函数。只不过这些函数必须按照特定的类型声明,以便内核能够以标准的方式传递处理程序的信息。中断处理程序与其他内核函数的真正区别在于:中断处理程序是被内核调用来响应中断的,而它们运行于我们称之为中断上下文的特殊上下文中。 中断可能随时发生,因此中断处理程序也就随时可能执行。所以必须保证中断处理程序能够快速执行,这样才能保证尽可能快地恢复中断代码的执行。因此,尽管对硬件而言,迅速对其中断进行服务非常重要,但对系统的其他部分而言,让中断处理程序在尽可能短的时间内完成运行也同样重要。 即使是最精简版的中断服务程序,它也要与硬件进行交互,告诉该设备中断已被接收。我们可以考虑一下网络设备的中断处理程序面临的挑战。该处理程序除了要对硬件应答,还要把来自硬件的网络数据包拷贝到内存,对其进行处理后再交给合适的协议栈或应用程序。显而易见,这种工作量不会太小,尤其对于如今的千兆比特和万兆比特以太网卡而言。 因此我们一般把中断处理切为两个部分或两半。中断处理程序是上半部 (top half)接收到一个中断,它就立即开始执行,但只做有严格时限的工作,例如对接收的中断进行应答或复位硬件,这些工作都是在所有中断被禁止的情况下完成的。能够被允许稍后完成的工作会推迟到下半部(bottom half)去。此后,在合适的时机,下半部会被开中断执行。 以网卡作为实例,当网卡接收流入网络的数据包时,需要通知内核数据包到了。网卡需要立即完成这件事,从而优化网络的吞吐量和传输周期,以避免超时。因此,网卡立即发出中断:嘀,内核,我这里有最新数据包了。内核通过执行网卡已注册的中断处理程序来做出应答。 中断开始执行,应答硬件,拷贝最新的网络数据包到内存,然后读取网卡更多的数据包。这些都是重要、紧迫而又与硬件相关的工作。处理和操作数据包的其他工作在随后的下半部中进行。深入剖析Linux中断机制之二Linux中断的组织形式 【摘要】本文详解了Linux内核的中断实现机制。首先介绍了中断的一些基本概念,然后分析了面向对象的Linux中断的组织形式、三种主要数据结构及其之间的关系。随后介绍了Linux处理异常和中断的基本流程,在此基础上分析了中断处理的详细流程,包括保存现场、中断处理、中断退出时的软中断执行及中断返回时的进程切换等问题。最后介绍了中断相关的API,包括中断注册和释放、中断关闭和使能、如何编写中断ISR、共享中断、中断上下文中断状态等。【关键字】中断,异常,hw_interrupt_type,irq_desc_t,irqaction,asm_do_IRQ,软中断,进程切换,中断注册释放request_irq,free_irq,共享中断,可重入,中断上下文 1 Linux中断的组织形式1.1 IRQ描述符irq_desc对于每个IRQ中断线,Linux都用一个irq_desc_t数据结构来描述,我们把它叫做IRQ描述符,NR_IRQS个IRQ形成一个全局数组irq_desc,其定义在/include/linux/irq.h中: struct irq_desc 中断描述符 148struct irq_desc 149 irq_flow_handler_t handle_irq; 150 struct irq_chip *chip; 151 void *handler_data; 152 void *chip_data; 153 struct irqaction *action; /* IRQ action list */ 154 unsigned int status; /* IRQ status */ 155 156 unsigned int depth; /* nested irq disables */ 157 unsigned int wake_depth; /* nested wake enables */ 158 unsigned int irq_count; /* For detecting broken IRQs */ 159 unsigned int irqs_unhandled; 160 spinlock_t lock; 161#ifdef CONFIG_SMP 162 cpumask_t affinity; 163 unsigned int cpu; 164#endif 171 const char *name; 172 _cacheline_aligned; 173 174extern struct irq_desc irq_descNR_IRQS; handle_irq:上层的通用中断处理函数指针,如果未设置则默认为_do_IRQ()。通常针对电平触发或者边沿触发有不同的处理函数。每个中断线可分别设置;chip:底层中断的各种控制访问方法集合,各个CPU实现的都不同,这属于面向对象的中断处理方式中最底层的一部分;handler_data:附加参数,用于handle_irq;chip_data:平台相关的附加参数,用于chip;action:指向一个单向链表的指针,这个链表就是对中断服务例程进行描述的irqaction结构;status:中断当前的状态;depth:中断关闭打开的层数。如果启用这条IRQ中断线,depth则为0,如果禁用这条IRQ中断线不止一次,则为一个正数。如果depth等于0,每当调用一次disable_irq( ),该函数就对这个域的值加1,同时该函数就禁用这条IRQ中断线。相反,每当调用enable_irq( )函数时,该函数就对这个域的值减1;如果depth变为0,该函数就启用这条IRQ中断线。Lock:此中断描述符为全局共享暑假,对于SMP需要互斥访问Dir: /proc/irq/ 入口Name: /proc/interrupts 中显示的中断名称“_cacheline_aligned”表示这个数据结构的存放按32字节(高速缓存行的大小)进行对齐,以便于将来存放在高速缓存并容易存取 linux+v2.6.19/arch/arm/kernel/irq.c 157void _init init_IRQ(void) 158 159 int irq; 160 161 for (irq = 0; irq NR_IRQS; irq+) 162 irq_descirq.status |= IRQ_NOREQUEST | IRQ_DELAYED_DISABLE | 163 IRQ_NOPROBE; 164 165#ifdef CONFIG_SMP 166 bad_irq_desc.affinity = CPU_MASK_ALL; 167 bad_irq_desc.cpu = smp_processor_id(); 168#endif 169 init_arch_irq(); 170 1.2 中断控制器描述符irq_chip 由于CPU不同,故每个处理器对于中断的处理方式不一样。Linux为了实现统一的中断处理,提供了底层的中断处理抽象接口,对于每个平台都需要实现底层的接口函数。这样对于上层的中断通用处理程序就无需任何改动。 struct irq_chip 片级的中断描述符 94struct irq_chip 95 const char *name; 96 unsigned int (*startup)(unsigned int irq); 97 void (*shutdown)(unsigned int irq); 98 void (*enable)(unsigned int irq); 99 void (*disable)(unsigned int irq); 100 101 void (*ack)(unsigned int irq); 102 void (*mask)(unsigned int irq); 103 void (*mask_ack)(unsigned int irq); 104 void (*unmask)(unsigned int irq); 105 void (*eoi)(unsigned int irq); 106 107 void (*end)(unsigned int irq); 108 void (*set_affinity)(unsigned int irq, cpumask_t dest); 109 int (*retrigger)(unsigned int irq); 110 int (*set_type)(unsigned int irq, unsigned int flow_type); 111 int (*set_wake)(unsigned int irq, unsigned int on); 121 const char *typename; 122; Name:用于/proc/interruptsStartup:默认为enable if NULLShutdown:默认为 disable if NULLEnable:允许中断,默认为unmask if NULLDisable:禁止中断,默认为mask if NULLAck:响应一个中断Mask:mask 一个中断源,通常是关闭中断mask_ack:响应并mask中断源unmask:unmask中断源set_type:设置中断触发方式IRQ_TYPE_LEVEL 大多数控制方法都是重复的,基本上只要有中断响应、中断屏蔽、中断开启、中断触发类型设置等方法就可以满足要求了。其他各种方法基本上和这些相同。 linux+v2.6.19/arch/arm/mach-at91rm9200/irq.c提供了中断响应、打开、关闭、设置触发类型等底层方法的接口static struct irq_chip at91_aic_chip = .name = AIC, .ack = at91_aic_mask_irq, .mask = at91_aic_mask_irq, .unmask = at91_aic_unmask_irq, .set_type = at91_aic_set_type, .set_wake = at91_aic_set_wake,; 124/* 125 * Initialize the AIC interrupt controller. 126 */ 127void _init at91_aic_init(unsigned int priorityNR_AIC_IRQS) 128 129 unsigned int i; 130 131 /* 132 * The IVR is used by macro get_irqnr_and_base to read and verify. 133 * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred. 134 */ 135 for (i = 0; i NR_AIC_IRQS; i+) 136 /* Put irq number in Source Vector Register: */ 137 at91_sys_write(AT91_AIC_SVR(i), i); 138 /* Active Low interrupt, with the specified priority */ 139 at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priorityi); 140 141 set_irq_chip(i, &at91_aic_chip); 142 set_irq_handler(i, do_level_IRQ); 143 set_irq_flags(i, IRQF_VALID | IRQF_PROBE); 144 145 /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */ 146 if (i 8) 147 at91_sys_write(AT91_AIC_EOICR, 0); 148 149 150 /* 151 * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS 152 * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU 153 */ 154 at91_sys_write(AT91_AIC_SPU, NR_AIC_IRQS); 155 156 /* No debugging in AIC: Debug (Protect) Control Register */ 157 at91_sys_write(AT91_AIC_DCR, 0); 158 159 /* Disable and clear all interrupts initially */ 160 at91_sys_write(AT91_AIC_IDCR, 0xFFFFFFFF); 161 at91_sys_write(AT91_AIC_ICCR, 0xFFFFFFFF); 162 163 以下这些宏定义都是为保持兼容性而设置的,后续版本中将彻底删除 47#define do_level_IRQ handle_level_irq 48#define do_edge_IRQ handle_edge_irq 49#define do_simple_IRQ handle_simple_irq 50#define irqdesc irq_desc 51#define irqchip irq_chip 55#define SA_INTERRUPT IRQF_DISABLED 57#define SA_SHIRQ IRQF_SHARED 60 61#define SA_TRIGGER_LOW IRQF_TRIGGER_LOW 62#define SA_TRIGGER_HIGH IRQF_TRIGGER_HIGH 63#define SA_TRIGGER_FALLING IRQF_TRIGGER_FALLING 64#define SA_TRIGGER_RISING IRQF_TRIGGER_RISING 65#define SA_TRIGGER_MASK IRQF_TRIGGER_MASK linux/kernel/irq/chip.chandle_level_irq 1.3 中断服务例程描述符irqaction在IRQ描述符中我们看到指针action的结构为irqaction,它是为多个设备能共享一条中断线而设置的一个数据结构,代表了每个注册中断对应的信息。在include/linux/interrupt.h中定义如下: 67typedef irqreturn_t (*irq_handler_t)(int, void *); 68 69struct irqaction 70 irq_handler_t handler; 71 unsigned long flags; 72 cpumask_t mask; 73 const char *name; 74 void *dev_id; 75 struct irqaction *next; 76 int irq; 77 struct proc_dir_entry *dir; 78; Handler:指向一个具体I/O设备的中断服务例程。这是允许多个设备共享同一中断线的关键域,中断线可以相同,但处理函数可以不一样。Flags:用一组标志描述中断线与I/O设备之间的关系。SA_INTERRUPT 中断处理程序必须以禁用中断来执行。此标志表明给定的中断处理程序是一个快速中断处理程序(fast interrupt handler)。过去,Linux将中断处理程序分为快速和慢速两种。那些可以迅速执行但调用频率可能会很高的中断服务程序,会被贴上这样的标签。通常这样做需要修改中断处理程序的行为,使它们能够尽可能快地执行。现在,加不加此标志的区别只剩下一条了:在本地处理器上,快速中断处理程序在禁止所有中断的情况下运行。这使得快速中断处理程序能够不受其他中断干扰,得以迅速执行。而默认情况下(没有这个标志),除了正运行的中断处理程序对应的那条中断线被屏蔽外,其他所有中断都是激活的。除了时钟中断外,绝大多数中断都不使用该标志。SA_SHIRQ 此标志表明可以在多个中断处理程序之间共享中断线。在同一个给定线上注册的每个处理程序必须指定这个标志:否则,在每条线上只能有一个处理程序。各项该中断线的每一个例程都需要设置此标志。 Name:I/O设备名(通过读取/proc/interrupts文件,可以看到,在列出中断号时也显示设备名。)dev_id:对于共享中断,此特定值用来区分各中断。当一个中断处理程序需要释放时,dev_id将提供惟一的标志信息(cookie),以便从共享中断线的诸多中断处理程序中删除指定的那一个。如果没有这个参数,那么内核不可能知道在给定的中断线上到底要删除哪一个处理程序。 如果无需共享中断线,那么将该参数赋为空值(NULL)就可以了,但是,如果中断线是被共享的,那么就必须传递惟一的信息。另外,内核每次调用中断处理程序时,都会把这个指针传递给它。实践中往往会通过它传递驱动程序的设备结构:这个指针是惟一的,而且有可能在中断处理程序内及设备模式中被用到。 Next:指向irqaction描述符链表的下一个元素。共享同一中断线的每个硬件设备都有其对应的中断服务例程,链表中的每个元素就是对相应设备及中断服务例程的描述。 Irq:对应的中断号dir:proc文件系统对应的入口 1.4 三者的关系三个主要的数据结构包含了与 IRQ 相关的所有信息:hw_interrupt_type、irq_desc_t 和 irqaction,下图解释了它们之间是如何关联的。中断服务例程ISR是irqaction 的Handler成员。 中断的处理是一种面向对象的机制,通过三个数据结果实现了三层结构,底层是和具体硬件相关的中断处理响应等,中间层是统一的中断处理流程,最上层是特定的中断处理例程。IRQ 结构之间的关系深入剖析Linux中断机制之三Linux对异常和中断的处理 Sailor_forever sailing_9806163.com 转载请注明/sailor_8318/archive/2008/07/09/2627136.aspx 【摘要】本文详解了Linux内核的中断实现机制。首先介绍了中断的一些基本概念,然后分析了面向对象的Linux中断的组织形式、三种主要数据结构及其之间的关系。随后介绍了Linux处理异常和中断的基本流程,在此基础上分析了中断处理的详细流程,包括保存现场、中断处理、中断退出时的软中断执行及中断返回时的进程切换等问题。最后介绍了中断相关的API,包括中断注册和释放、中断关闭和使能、如何编写中断ISR、共享中断、中断上下文中断状态等。【关键字】中断,异常,hw_interrupt_type,irq_desc_t,irqaction,asm_do_IRQ,软中断,进程切换,中断注册释放request_irq,free_irq,共享中断,可重入,中断上下文 1 Linux对异常和中断的处理1.1 异常处理Linux利用异常来达到两个截然不同的目的: 给进程发送一个信号以通报一个反常情况 管理硬件资源 对于第一种情况,例如,如果进程执行了一个被0除的操作,CPU则会产生一个“除法错误”异常,并由相应的异常处理程序向当前进程发送一个SIGFPE信号。当前进程接收到这个信号后,就要采取若干必要的步骤,或者从错误中恢复,或者终止执行(如果这个信号没有相应的信号处理程序)。 内核对异常处理程序的调用有一个标准的结构,它由以下三部分组成: 在内核栈中保存大多数寄存器的内容(由汇编语言实现) 调用C编写的异常处理函数 通过ret_from_exception()函数从异常退出。 1.2 中断处理当一个中断发生时,并不是所有的操作都具有相同的急迫性。事实上,把所有的操作都放进中断处理程序本身并不合适。需要时间长的、非重要的操作应该推后,因为当一个中断处理程序正在运行时,相应的IRQ中断线上再发出的信号就会被忽略。另外中断处理程序不能执行任何阻塞过程,如I/O设备操作。因此,Linux把一个中断要执行的操作分为下面的三类: 紧急的(Critical)这样的操作诸如:中断到来时中断控制器做出应答,对中断控制器或设备控制器重新编程,或者对设备和处理器同时访问的数据结构进行修改。这些操作都是紧急的,应该被很快地执行,也就是说,紧急操作应该在一个中断处理程序内立即执行,而且是在禁用中断的状态下。 非紧急的(Noncritical)这样的操作如修改那些只有处理器才会访问的数据结构(例如,按下一个键后,读扫描码)。这些操作也要很快地完成,因此,它们由中断处理程序立即执行,但在启用中断的状态下。 非紧急可延迟的(Noncritical deferrable)这样的操作如,把一个缓冲区的内容拷贝到一些进程的地址空间(例如,把键盘行缓冲区的内容发送到终端处理程序的进程)。这些操作可能被延迟较长的时间间隔而不影响内核操作,有兴趣的进程会等待需要的数据。 所有的中断处理程序都执行四个基本的操作: 在内核栈中保存IRQ的值和寄存器的内容。 给与IRQ中断线相连的中断控制器发送一个应答,这将允许在这条中断线上进一步发出中断请求。 执行共享这个IRQ的所有设备的中断服务例程(ISR)。 跳到ret_to_usr( )的地址后终止。 1.3 中断处理程序的执行流程1.3.1 流程概述现在,我们可以从中断请求的发生到CPU的响应,再到中断处理程序的调用和返回,沿着这一思路走一遍,以体会Linux内核对中断的响应及处理。 假定外设的驱动程序都已完成了初始化工作,并且已把相应的中断服务例程挂入到特定的中断请求队列。又假定当前进程正在用户空间运行(随时可以接受中断),且外设已产生了一次中断请求,CPU就在执行完当前指令后来响应该中断。 中断处理系统在Linux中的实现是非常依赖于体系结构的,实现依赖于处理器、所使用的中断控制器的类型、体系结构的设计及机器本身。 设备产生中断,通过总线把电信号发送给中断控制器。如果中断线是激活的,那么中断控制器就会把中断发往处理器。在大多数体系结构中,这个工作就是通过电信号给处理器的特定管脚发送一个信号。除非在处理器上禁止该中断,否则,处理器会立即停止它正在做的事,关闭中断系统,然后跳到内存中预定义的位置开始执行那里的代码。这个预定义的位置是由内核设置的,是中断处理程序的入口点。 对于ARM系统来说,有个专用的IRQ运行模式,有一个统一的入口地址。假定中断发生时CPU运行在用户空间,而中断处理程序属于内核空间,因此,要进行堆栈的切换。也就是说,CPU从TSS中取出内核栈指针,并切换到内核栈(此时栈还为空)。 若当前处于内核空间时,对于ARM系统来说是处于SVC模式,此时产生中断,中断处理完毕后,若是可剥夺内核,则检查是否需要进行进程调度,否则直接返回到被中断的内核空间;若需要进行进程调度,则svc_preempt,进程切换。 190 .align 5 191_irq_svc: 192 svc_entry 197#ifdef CONFIG_PREEMPT 198 get_thread_info tsk 199 ldr r8, tsk, #TI_PREEMPT get preempt count 200 add r7, r8, #1 increment it 201 str r7, tsk, #TI_PREEMPT 202#endif 203 204 irq_handler 205#ifdef CONFIG_PREEMPT 206 ldr r0, tsk, #TI_FLAGS get flags 207 tst r0, #_TIF_NEED_RESCHED 208 blne svc_preempt 209preempt_return: 210 ldr r0, tsk, #TI_PREEMPT read preempt value 211 str r8, tsk, #TI_PREEMPT restore preempt count 212 teq r0, r7 213 strne r0, r0, -r0 bug() 214#endif 215 ldr r0, sp, #S_PSR irqs are already disabled 216 msr spsr_cxsf, r0 221 ldmia sp, r0 - pc load r0 - pc, cpsr 222 223 .ltorg 当前处于用户空间时,对于ARM系统来说是处于USR模式,此时产生中断,中断处理完毕后,无论是否是可剥夺内核,都调转到统一的用户模式出口ret_to_user,其检查是否需要进行进程调度,若需要进行进程调度,则进程切换,否则直接返回到被中断的用户空间。 404 .align 5 405_irq_usr: 406 usr_entry 407 411 get_thread_info tsk 412#ifdef CONFIG_PREEMPT 413 ldr r8, tsk, #TI_PREEMPT get preempt count 414 add r7, r8, #1 increment it 415 str r7, tsk, #TI_PREEMPT 416#endif 417 418 irq_handler 419#ifdef CONFIG_PREEMPT 420 ldr r0, tsk, #TI_PREEMPT 421 str r8, tsk, #TI_PREEMPT 422 teq r0, r7 423 strne r0, r0, -r0 bug() 424#endif 428 429 mov why, #0 430 b ret_to_user 432 .ltorg 1.3.2 保存现场 105/* 106 * SVC mode handlers 107 */ 108 115 .macro svc_entry 116 sub sp, sp, #S_FRAME_SIZE 117 SPFIX( tst sp, #4 ) 118 SPFIX( bicne sp, sp, #4 ) 119 stmib sp, r1 - r12 120 121 ldmia r0, r1 - r3 122 add r5, sp, #S_SP here for interlock avoidance 123 mov r4, #-1 124 add r0, sp, #S_FRAME_SIZE 125 SPFIX( addne r0, r0, #4 ) 126 str r1, sp save the real r0 copied 127 from the exception stack 128 129 mov r1, lr 130 131 132 We are now ready to fill in the remaining blanks on the stack: 133 134 r0 - sp_svc 135 r1 - lr_svc 136 r2 - lr_, already fixed up for correct return/restart 137 r3 - spsr_ 138 r4 - orig_r0 (see pt_regs definition in ptrace.h) 139 140 stmia r5, r0 - r4 141 .endm 1.3.3 中断处理因为C的调用惯例是要把函数参数放在栈的顶部,因此pt- regs结构包含原始寄存器的值,这些值是以前在汇编入口例程svc_entry中保存在栈中
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 幼儿园围栏安全管理规范
- 建设企业培训体系实施纲要
- 护理诊断教学
- 插件员工培训体系构建
- 2025年水处理试题答案
- 基础教研室工作计划与总结模版
- 化工行业2025年一季报综述:基础化工盈利能力边际好转石油石化业绩随油价短期波动15865kb
- 山东省济宁市兖州区2024-2025学年高二下学期期中质量检测化学试卷(含答案)
- 小学信息技术老师上半年工作总结模版
- 2025年酒店保安年度总结模版
- 大数据与食品质量控制的深度融合-洞察阐释
- 水利工程施工文明措施与环保要求
- 2025年人教版小学六年级下册奥林匹克数学竞赛测试卷(附参考答案)
- 课题申报书:智能教育视角下基于眼动追踪的在线学习认知模型及自适应机制研究
- 2022石油化工消防设施维护保养技术标准
- (二模)2024~2025学年度苏锡常镇四市高三教学情况调研(二)生物试卷(含答案)
- 《康复技术》课件-胫腓骨骨折术后康复
- 光镊在细胞生物医学研究中的应用探索-全面剖析
- 北京开放大学2025年《企业统计》形考作业2答案
- “童”心协力 守护健康-校园传染病防控教育
- 直播电商基础试题及答案
评论
0/150
提交评论