免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2006 | 回复: 0
打印 上一主题 下一主题

ARM linux(uC)中断内幕 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-09-23 17:59 |只看该作者 |倒序浏览
uClinux和linux的最大的不同在于有没有MMU,无MMU的uClinux无法通过虚拟地址访问硬件,因此,其中断地址也与linux有所不同,linux的内核需要运行的3G以上的空间,因此,中断地址从0xFFFF0000开始,而uClinux则从0x00000000开始。而对于运行在无MMU的uClinux来讲,s3c4510和s3c44b0亦是不同的,s3c44b0不支持地址的remap,因此,内核运行后,一旦中断发生,内核都要到flash的0地址走一圈,而对于s3c4510来讲,其支持地址的remap,因此,整个系统都在ram空间执行,中断vector也被影射到ram空间,中断一旦发生,中断执行程序不需要到flash空间执行,只需在ram的0地址即可。
以上是我所接触到的linux的开启地址,下面详细讨论linux中断从开始到结束的一系列内部过程。
1.   异常向量表的初始化:系统启动时,通过start_kernel(init/main.c)
(rap_initarch/arm/kernel/traps.c)的调用关系,初始化系统的陷阱,即ARM处理器中包括中断在内的所有异常向量。当有异常发生时,处理器会跳转到对应的0Xffff0000起始的向量处取指令,然后,通过b指令散转到异常处理代码。因为ARM中的分支跳转指令(b指令)是相对跳转,而且只有+-32MB的寻址范围,所以把__stubs_start~__stubs_end之间的异常处理代码复制到乐0Xffff0200起始处。
2.      
异常的处理过程:对于ARM处理器上的外部中断都可以影射到irq或fiq上,以下主要分析irq的处理过程。对于irq的处理是从entry_armv .S文件的vector_IRQ标号开始的(此文件有关于arm所有的中断模式)。此段程序代码主要完成以下4个任务:
(1)将下一条指令的地址存入相应连接寄存器LR,以便程序在处理异常返回时能从正确的位置重新开始执行。若异常是从ARM状态进入,LR寄存器中保存的是下一条指令的地址(当前PC+4或PC+8,与异常的类型有关);若异常是从Thumb状态进入,则在LR寄存器中保存当前PC的偏移量,这样,异常处理程序就不需要确定异常是从何种状态进入的。例如:在软件中断异常SWI,指令
MOV PC,R14_svc总是返回到下一条指令,不管SWI是在ARM状态执行,还是在Thumb状态执行。
(2)将CPSR复制到相应的SPSR中。
(3)根据异常类型,强制设置CPSR的运行模式位。(在linux系统中处理器进入irq之前只有两种模式即usr模式和svc模式,其他模式下都不允许开启irq)
(4)强制PC从相关的异常向量地址取下一条指令执行,从而跳转到相应的异常处理程序处。接下来,只剖析当处理器进入irq之前处于svc模式的情况,即__irq_svc所对应的代码。__irq_usr的处理过程与__irq_svc类似。
  (1)把进入中断之前的CPSR和PC放入堆栈,以便中断返回时直接恢复
  (2)通过get_irqnr_and_base宏得到中断号(irq
number)。(主要是读取INTPND寄存器得到当前的中断,并使用一个循环把INTPND转换成中断号)
  (3)执行do_IRQ函数,当有中断发生时处理中断。
  (4)恢复寄存器,返回到发生中断前的代码中。
3.linux中断处理的相关函数
(1)request_irq函数:
数组irq_desc在arch/arm/kernel/irq.c中定义,它记录了系统中所有中断的状态,开启或关闭的方法及中断回调函数等信息。系统每添加一个中断,使用kmalloc函数为结构体irqaction申请空间,把中断相关的信息保存在一个结构提irqaction中。
Irqaction的大多数成员与request_irq函数的参数对应。其定义的next使得irqaction组成了一个单向链表,这就解决了在共享中断中记录不同的中断子程序入口问题。
函数setup_arm_irq实现了向数组irq_desc中添加新分配的action。
可见,函数request_irq所完成的工作主要是分配并填充一个新的irqaction结构,并把它添加到irq_des      action    handler(……)c数组所对应的中断号中,因此,当有中断发生时,可通过执行irq_desc函数实现对所注册的中断处理子程序的调用。
(2)do_IRQ函数:
首先通过fixup_irq函数把irq进行重新映射。fixup_irq是与具体的处理器相关的函数。把所有中断和内部子中断都映射给系统,利用全局数组irq_desc、中断注册函数request_irq等进行统一处理。经过fixup_irq以后的irq对应request_irq的中断号。至此,终于找到了request_irq中所注册的irqaction结构。在调用handler之前,必须根据中断的属性处理一些事情。然后通过链表依次调用irqaction结构中的函数。对于非共享中断,这个循环只执行一次。
以上是我对ARM linux(uC)中断的个人理解,若有不当之处,请与我联系,让我一起致力于linux内核的研究。
E_mail:wujinlei_82@163.com
感谢女友在国庆期间一直默默的支持着我!
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/76419/showart_1219282.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP