本发明涉及通信领域,具体涉及一种linux的快速异常处理方法及装置。
背景技术:
中断或系统调用开销就是中断的响应过程的时间,中断的响应过程是当有事件产生,进入中断之前必须先记住当前正在做的事情,然后去处理发生的事情,处理这个过程的时间,叫做中断响应开销。基本定义就是:从发出中断请求到进入中断处理所用的时间。
对于占先式内核,要先调用一个特定的函数,该函数通知内核即将进行中断服务,使得内核可以跟踪中断的嵌套。占先式内核的中断响应时间由下式给出:中断响应时间=关中断的最长时间+保存cpu内部寄存器的时间+进入中断服务函数的执行时间+开始执行中断服务例程(isr)的第一条指令时间。对于频繁的中断来说,“保存cpu内部寄存器的时间”往往占据了中断响应时间的一大部分。
对于嵌入式linux系统来说,其运行过程中,会有大量的系统调用或者外部中断产生。即使是正常运行的代码,由于硬件tlb(传输后备缓冲器)条数的限制,也会产生大量的tlb异常,在用户态到内核态上下文切换过程中,会导致寄存器的保存和恢复。耗时巨大,特别是对于频繁发生并且处理时间很短的中断或异常来说,大量的cpu消耗都用在了通用寄存器和内存之间的备份恢复过程了。
技术实现要素:
有鉴于此,本发明提供一种linux的快速异常处理方法及装置,能够在以嵌入式主流处理器(ppc,arm等)为基础的系统中减少中断处理开销时间。
一方面,本发明实施例提出一种linux的快速异常处理方法,包括:
s1、编译主程序和中断处理程序,并禁用属于set2类的寄存器;
s2、使用预设的映射关系,将编译后的中断处理程序中属于set1类的寄存器替换为属于set2类的寄存器,其中,所述set2类和set1类为通过将处理器的寄存器中需要保存的寄存器划分为数量相同的两组寄存器得到的;
s3、将编译后的主程序和替换后的中断处理程序链接起来,并执行。
另一方面,本发明实施例提出一种linux的快速异常处理装置,包括:
第一编译单元,用于编译主程序和中断处理程序,并禁用属于set2类的寄存器;
替换单元,用于使用预设的映射关系,将编译后的中断处理程序中属于set1类的寄存器替换为属于set2类的寄存器,其中,所述set2类和set1类为通过将处理器的寄存器中需要保存的寄存器划分为数量相同的两组寄存器得到的;
执行单元,用于将编译后的主程序和替换后的中断处理程序链接起来,并执行。
本发明实施例提供的linux的快速异常处理方法及装置,在编译主程序和中断处理程序时,禁用属于set2类的寄存器,并使用预设的映射关系,将编译后的中断处理程序中属于set1类的寄存器替换为属于set2类的寄存器,则执行时主程序和中断处理程序中分别只包含set1类和set2类寄存器,即本方案采用两套寄存器组实现内核态用户态隔离,两套寄存器为通过将处理器的寄存器中需要保存的寄存器划分为数量相同的两组寄存器得到的,能保证内核态用户态一致,两套寄存器组运行时相互独立,互不干扰,内核态和用户态固定使用其中一套寄存器组,避免了从用户态陷入到内核态,或者从内核态退出到用户态时,大量的通用寄存器保存恢复的过程,即从用户态到内核态切换时无需保存上下文,从而能减少中断处理开销时间,另外,本方案不局限于具体的cpu架构,可应用x86,mips,ppc等多种架构的处理器。
附图说明
图1为本发明linux的快速异常处理方法一实施例的流程示意图;
图2为本发明linux的快速异常处理装置一实施例的结构示意图。
具体实施方式
为使本发明实施例的目的、技术方案和优点更加清楚,下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚地描述,显然,所描述的实施例是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
用户态到内核态切换途径有如下三种:
1:系统调用;2:中断;3:异常。
1.用户空间的应用程序,通过系统调用,进入内核空间。这个时候用户空间的进程要传递很多变量、参数的值给内核,内核态运行的时候也要保存用户进程的一些寄存器值、变量等。所谓的“进程上下文”,可以看作是用户进程传递给内核的这些参数以及内核要保存的那一整套的变量和寄存器值和当时的环境等。
2.硬件通过触发信号,导致内核调用中断处理程序,进入内核空间。这个过程中,硬件的一些变量和参数也要传递给内核,内核通过这些参数进行中断处理。所谓的“中断上下文”,其实也可以看作就是硬件传递过来的这些参数和内核,以及需要保存的一些其他环境(主要是当前被打断执行的进程环境)。
3.系统运行发生异常,例如除0,或者tlbmiss等,进入内核态。与2一样,需要保存一整套的变量和寄存器值和当时的环境等。
对于大多数cpu架构来说,上下文切换的方法是软件上下文保存/恢复。在该方法中,主要的寄存器在一个中断例程开始时被保存软件命令保存,并在中断例程结束时通过软件命令恢复。如果中断处理程序被写在一个高级编程语言,例如,不允许程序员指定哪个特定的寄存器来使用,编译器可以简单地保存和恢复所有的寄存器。这是十分耗时的。例如,mips处理器有20多个寄存器,中断处理程序开始和结束时必须正确的保存和恢复。如果中断例程只使用几个寄存器,该方法也将是十分低效的。如果在程序执行过程中经常调用中断程序,这种性能的损耗将是巨大的。
这种方法的一个主要特点是用汇编语言编写中断处理程序,使程序员可以控制寄存器用于中断处理程序。程序员增加了寄存器的保存和恢复命令,保存和恢复在异常例程中使用的寄存器。使用汇编语言编写中断处理程序,虽然能够更有效利用处理器资源,但与高级语言相比,编写软件时更为耗时并容易出错。
还有一种上下文切换的方法是硬件上下文保存/恢复。在该方法中,在中断被响应时,硬件自动执行上下文保存时,在中断例程结束时,并自动执行上下文恢复。与软件控制的上下文切换相比,硬件上下文保存/恢复虽然也耗时,开销却要小得多。但不是所有的处理器都支持硬件上下文切换。
申请人在实施本发明的过程中发现,在大多数操作中,编译器通常只使用所有可用寄存器中的一小部分。因此,保留一部分寄存器用做中断处理程序,而其余的寄存器由主程序使用。此方法将使在中断处理程序入口和退出点上保存和恢复寄存器的耗时降到最低。基于此,参看图1,本实施例公开一种linux的快速异常处理方法,包括:
s1、编译主程序和中断处理程序(编译后的主程序和中断处理程序为二进制代码),并禁用属于set2类的寄存器;
s2、使用预设的映射关系,将编译后的中断处理程序中属于set1类的寄存器替换为属于set2类的寄存器,其中,所述set2类和set1类为通过将处理器的寄存器中需要保存的寄存器划分为数量相同的两组寄存器得到的;
s3、将编译后的主程序和替换后的中断处理程序链接起来,并执行。
本发明实施例提供的linux的快速异常处理方法,在编译主程序和中断处理程序时,禁用属于set2类的寄存器,并使用预设的映射关系,将编译后的中断处理程序中属于set1类的寄存器替换为属于set2类的寄存器,则执行时主程序和中断处理程序中分别只包含set1类和set2类寄存器,即本方案采用两套寄存器组实现内核态用户态隔离,两套寄存器为通过将处理器的寄存器中需要保存的寄存器划分为数量相同的两组寄存器得到的,能保证内核态用户态一致,两套寄存器组运行时相互独立,互不干扰,内核态和用户态固定使用其中一套寄存器组,避免了从用户态陷入到内核态,或者从内核态退出到用户态时,大量的通用寄存器保存恢复的过程,即从用户态到内核态切换时无需保存上下文,从而能减少中断处理开销时间,另外,本方案不局限于具体的cpu架构,可应用x86,mips,ppc等多种架构的处理器。
下面以mips处理器为例,对本发明set1类和set2类寄存器组的划分进行详细说明:
mips处理器有32个通用寄存器,从这些寄存器中选出需要保存的寄存器,划分为set1类和set2类。比如可以使set1类中包括如下寄存器:寄存器at、寄存器t0、寄存器t1、寄存器t2、寄存器s0、寄存器s1、寄存器s2、寄存器s3和寄存器v0,使set2类中包括如下寄存器:寄存器t3、寄存器t4、寄存器t5、寄存器t6、寄存器t7、寄存器s4、寄存器s5、寄存器s6和寄存器s7。可以理解的是,set1类和set2类的划分只需要保证数量相同(均为需要保存的寄存器数量的一般)、寄存器不重合即可。
对于所述映射关系,只需要保证为一一映射即可,比如所述映射关系可以为:将寄存器at映射为寄存器t3,将寄存器t0映射为寄存器t5,将寄存器t2映射为寄存器t7,将寄存器v0映射为寄存器t4,将寄存器t1映射为寄存器t6,将寄存器s0映射为寄存器s4,将寄存器s1映射为寄存器s5,将寄存器s2映射为寄存器s6,将寄存器s3映射为寄存器s7。
在前述方法实施例的基础上,若所述主程序和中断处理程序采用高级语言编写,则所述s1,可以包括:
编译主程序为二进制代码,中断处理程序为汇编代码;
在所述s3之前,还可以包括:
将中断处理程序编译为二进制代码。
本实施例中,使用高级语言编写主程序和中断处理程序,在汇编代码中进行寄存器替换处理,一方面不用担心汇编无法实现复杂功能的问题,另一方面,因为二进制代码包含的信息比汇编代码复杂,使得本方案相较于前述实施例能够在替换时降低出错几率。
参看图2,本实施例公开一种linux的快速异常处理装置,包括:
第一编译单元1,用于编译主程序和中断处理程序,并禁用属于set2类的寄存器;
替换单元2,用于使用预设的映射关系,将编译后的中断处理程序中属于set1类的寄存器替换为属于set2类的寄存器,其中,所述set2类和set1类为通过将处理器的寄存器中需要保存的寄存器划分为数量相同的两组寄存器得到的;
执行单元3,用于将编译后的主程序和替换后的中断处理程序链接起来,并执行。
本发明实施例提供的linux的快速异常处理装置,在编译主程序和中断处理程序时,禁用属于set2类的寄存器,并使用预设的映射关系,将编译后的中断处理程序中属于set1类的寄存器替换为属于set2类的寄存器,则执行时主程序和中断处理程序中分别只包含set1类和set2类寄存器,即本方案采用两套寄存器组实现内核态用户态隔离,两套寄存器为通过将处理器的寄存器中需要保存的寄存器划分为数量相同的两组寄存器得到的,能保证内核态用户态一致,两套寄存器组运行时相互独立,互不干扰,内核态和用户态固定使用其中一套寄存器组,避免了从用户态陷入到内核态,或者从内核态退出到用户态时,大量的通用寄存器保存恢复的过程,即从用户态到内核态切换时无需保存上下文,从而能减少中断处理开销时间,另外,本方案不局限于具体的cpu架构,可应用x86,mips,ppc等多种架构的处理器。
在前述装置实施例的基础上,若所述主程序和中断处理程序为汇编代码,则所述第一编译单元,具体可以用于:
编译主程序为二进制代码,中断处理程序为汇编代码;
所述装置还可以包括:
第二编译单元,用于在所述执行单元工作之前,将中断处理程序编译为二进制代码。
在前述装置实施例的基础上,若所述处理器为mips处理器,
所述set1类可以包括:寄存器at、寄存器t0、寄存器t1、寄存器t2、寄存器s0、寄存器s1、寄存器s2、寄存器s3和寄存器v0,所述set2类可以包括:寄存器t3、寄存器t4、寄存器t5、寄存器t6、寄存器t7、寄存器s4、寄存器s5、寄存器s6和寄存器s7,
所述映射关系可以为:将寄存器at映射为寄存器t3,将寄存器t0映射为寄存器t5,将寄存器t2映射为寄存器t7,将寄存器v0映射为寄存器t4,将寄存器t1映射为寄存器t6,将寄存器s0映射为寄存器s4,将寄存器s1映射为寄存器s5,将寄存器s2映射为寄存器s6,将寄存器s3映射为寄存器s7。
与现有的技术比较,本发明具有如下优点:
1、真正实现快速系统调用或者快速异常中断处理,而且与具体的处理内容无关。它允许非常快速的上下文切换。
2、节省内核态栈空间,使内存利用更高效。
3、本发明允许通过c或其他高级语言实行中断例程。相比以前需要使用汇编语言编写中断处理程序来减小上下文开销,而且中断处理还不能过于复杂而言,灵活度大大增强。
虽然结合附图描述了本发明的实施方式,但是本领域技术人员可以在不脱离本发明的精神和范围的情况下做出各种修改和变型,这样的修改和变型均落入由所附权利要求所限定的范围之内。