加入收藏 | 设为首页 | 会员中心 | RSS
您当前的位置:首页 > Linux技术 > Linux嵌入式

浅析armlinux 2.4.19中断irq分发例程的派发流程之根基

时间:2008-06-06 11:46:44  来源:  作者:
应用程序运行在user模式,对应arm的cpsr&15的值为0,而内核代码运行在svc模式,对应arm的cpsr&15的值为3,
所以,如果应用程序在运行期间,即usr模式下,arm发生了irq中断,那么中断处理代码得知后会调用__irq_usr分发处理例程处理irq中断,如果在系统调用syscall之类使程序运行在内核空间执行内核程序的时候,即svc模式下,arm发生了irq中断,那么中断处理代码得知后会调用__irq_svc分发处理例程处理irq中断,中断程序是怎么识别svc和usr模式,进而派发相应的__irq_usr和__irq_svc分发例程的呢,来看看代码部分:
//1.arch/arm/kernel/entry-armv.S
...
.LCvswi:    .word    vector_swi

.LCsirq:    .word    __temp_irq
.LCsund:    .word    __temp_und
.LCsabt:    .word    __temp_abt

__stubs_end:

        .equ    __real_stubs_start,.LCvectors+0x200

.LCvectors:    swi    SYS_ERROR0
        b    __real_stubs_start+(vector_undefinstr-__stubs_start)
        ldr    pc,__real_stubs_start+(.LCvswi-__stubs_start)
        b    __real_stubs_start+(vector_prefetch-__stubs_start)
        b    __real_stubs_start+(vector_data-__stubs_start)
        b    __real_stubs_start+(vector_addrexcptn-__stubs_start)
//irq中断发生后,cpu捕获中断,跳转到这里执行vector_IRQ处理程序[gliethttp_20071225]
//中断处理代码位于0xFFFF0000地址之后的空间中,
//为了更透彻的理解,最好先看看另3篇文章
//《浅析arm-linux中断vector向量表的建立流程》
//《浅析armlinux-setup_arch()->create_mapping()函数5-2-2》
//《浅析arm-linux系统调用的流程》
//文章1:http://blog.chinaunix.net/u1/38994/showart_333925.html
//文章2:http://blog.chinaunix.net/u1/38994/showart_353785.html
//文章3:http://blog.chinaunix.net/u1/38994/showart_331915.html
//为了更好理解上面的这几篇文章,最好先看看《浅析armlinux2.4.19启动程序[head-armv.s文件]》
//文章4:http://blog.chinaunix.net/u1/38994/showart_346701.html
        b    __real_stubs_start+(vector_IRQ-__stubs_start)
        b    __real_stubs_start+(vector_FIQ-__stubs_start)
...
//2.arch/arm/kernel/entry-armv.S
...
vector_IRQ:    @
        @ save mode specific registers
        @
        ldr    r13,.LCsirq    //取出LCsirq变量的地址,用来存放lr
        sub    lr,lr,#4        //lr-4,这是arm必须的
        str    lr,[r13]        //将计算之后的返回地址lr存入LCsirq变量
//读取此次irq中断发生时,cpu所处模式spsr,即,中断发生时cpu正在用户空间运行用户应用程序,
//还是在内核空间svc模式下运行内核代码,lr&15的数值为arm进入irq之前cpu运行的模式值
//如果lr&15=0表示,此次irq中断发生时,cpu正运行用户空间的用户程序,
//如果lr&15=3表示,此次irq中断发生时,cpu正运行内核空间的内核代码[gliethttp_20071225]
        mrs    lr,spsr
        str    lr,[r13,#4]

        mrs    r13,cpsr
        bic    r13,r13,#MODE_MASK
        orr    r13,r13,#I_BIT|MODE_SVC
//切换到svc模式,因为当前cpsr为irq模式,所以可以修改cpsr,
//注意在usr模式下cpsr的数值,即使使用了msr spsr_c, r13赋值语句,
//因为usr模式不允许修改cpsr,所以r13的数值并不能被真正赋值给spsr,
//执行完赋值语句之后,spsr的数值不会发生任何改变,仍然是原来的值[gliethttp_20071225]
        msr    spsr_c,r13    

        and    lr,lr,#15
//lr&15的值为发生irq之前cpu所在的空间,
//0:在用户空间发生了irq中断
//3:在内核空间发生了irq中断
//lr<<2=lr*4也就是pc+0和pc+12
//分别对应LCtab_irq的.word __irq_usr域和.word __irq_svc域
        ldr    lr,[pc,lr,lsl#2]
//跳转到__irq_usr或者__irq_svc处理此次irq中断[gliethttp_20071225]
        movs    pc,lr

.LCtab_irq: .word    __irq_usr            @ 0(USR_26/USR_32)//用户空间发生irq中断
        .word    __irq_invalid            @ 1(FIQ_26/FIQ_32)
        .word    __irq_invalid            @ 2(IRQ_26/IRQ_32)
        .word    __irq_svc                @ 3(SVC_26/SVC_32)//内核空间发生irq中断
        .word    __irq_invalid            @ 4
        .word    __irq_invalid            @ 5
        .word    __irq_invalid            @ 6
        .word    __irq_invalid            @ 7
        .word    __irq_invalid            @ 8
        .word    __irq_invalid            @ 9
        .word    __irq_invalid            @ a
        .word    __irq_invalid            @ b
        .word    __irq_invalid            @ c
        .word    __irq_invalid            @ d
        .word    __irq_invalid            @ e
        .word    __irq_invalid            @ f
...
.LCvswi:    .word    vector_swi
.LCsirq:    .word    __temp_irq
.LCsund:    .word    __temp_und
.LCsabt:    .word    __temp_abt
...
来顶一下
近回首页
返回首页
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
推荐资讯
相关文章
    无相关信息
栏目更新
栏目热门