我是靠谱客的博主 感性火龙果,最近开发中收集的这篇文章主要介绍linux中断处理汇编入口,linux驱动之中断处理过程汇编部分,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

linux系统下驱动中,中断异常的处理过程,与裸机开发中断处理过程非常类似。通过简单的回顾裸机开发中断处理部分,来参考学习linux系统下中断处理流程。

一、ARM裸机开发中断处理过程

以S3C2440的裸机开发启动文件中,有关irq中断部分代码为例进行说明:

.extern main

.text

.global _start_start:b ResetHandleUndef:b HandleUndefHandleSWI:b HandleSWIHandlePrefetchAbort:b HandlePrefetchAbortHandleDataAbort:b HandleDataAbortHandleNotUsed:b HandleNotUsed

b HandleIRQHandleFIQ:b HandleFIQReset:ldr sp, =4096@ 设置栈指针,以下都是C函数,调用前需要设好栈

bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启

msr cpsr_c, #0xd2 @ 进入中断模式

ldr sp, =3072@ 设置中断模式栈指针

msr cpsr_c, #0xdf @ 进入系统模式

ldr sp, =4096@ 设置系统模式栈指针

bl init_led @ 初始化LED的GPIO管脚

bl init_irq @ 调用中断初始化函数,在init.c中

msr cpsr_c, #0x5f @ 设置I-bit=0,开IRQ中断

ldr lr, =halt_loop @ 设置返回地址

ldr pc, =main @ 调用main函数halt_loop:b halt_loopHandleIRQ:

sub lr, lr, #4@ 计算返回地址

stmdb sp!, { r0-r12,lr } @ 保存使用到的寄存器

@ 注意,此时的sp是中断模式的sp,初始值是上面设置的3072

ldr lr, =int_return @ 设置调用ISR即EINT_Handle函数后的返回地址

ldr pc, =EINT_Handle @ 调用中断服务函数,在interrupt.c中int_return:ldmia sp!, { r0-r12,pc }^ @ 中断返回, ^表示将spsr的值复制到cpsr

当irq中断发生时,一些列的处理流程如下:

1、硬件自动令PC置为irq的中断向量,从而执行跳转指令“b HandleIRQ”。

其实,之前还伴随着保存中断断点地址到lr(还要换算);CPSR的值到SPSR;将CPSR切换到异常模式。

2、保存中断现场

sub lr, lr, #4 @ 计算返回地址

stmdb sp!, { r0-r12,lr } @ 保存使用到的寄存器

3、执行中断服务程序

ldr lr, =int_return @ 设置调用ISR即EINT_Handle函数后的返回地址

ldr pc, =EINT_Handle @ 调用中断服务函数,在interrupt.c中

4、从中断异常工作模式返回

int_return:

ldmia sp!, { r0-r12,pc }^ @ 中断返回, ^表示将spsr的值复制到cpsr

二、linux系统中断处理流程

1、ARM异常向量表

arch/arm/kernel/entry-armv.S

.globl __vectors_start__vectors_start:swi SYS_ERROR0 /* 复位时,执行这条指令 */

b vector_und + stubs_offset /* 未定义异常 */

ldr pc, .LCvswi + stubs_offset /* swi异常 */

b vector_pabt + stubs_offset /* 指令预取异常 */

b vector_dabt + stubs_offset /* 数据访问终止 */

b vector_addrexcptn + stubs_offset /* 没有用 */

b vector_irq + stubs_offset /* irq异常 */

b vector_fiq + stubs_offset /* fiq异常 */

.globl __vectors_end__vectors_end:

异常向量表,无非还是一些跳转指令。当发生irq中断,执行指令“b vector_irq + stubs_offset”,也就是跳转到vector_irq代码段继续执行。

在linux内核初始化阶段,start_kernel函数(init/main.c)会调用trap_init、init_IRQ两个函数来初始化异常向量相关处理函数。简要说明就是,将异常向量表拷贝到地址0xffff0000处(ARM体系协处理器寄存器c1能设置异常向量的基地址为0xffff0000),再把异常向量表中异常处理的进一步函数代码段拷贝到0xffff0200位置(vector_und、vector_irq等)。

2、异常处理进一步函数----vector_irq

arch/arm/kernel/entry-armv.S

1 .globl __stubs_start2 __stubs_start:

3 vector_stub irq, IRQ_MODE, 4

4 .long __irq_usr @ 0(USR_26 / USR_32)5 .long __irq_invalid @ 1(FIQ_26 / FIQ_32)6 .long __irq_invalid @ 2(IRQ_26 / IRQ_32)7 .long __irq_svc @ 3(SVC_26 / SVC_32)8 .long __irq_invalid @ 4

9 .long __irq_invalid @ 5

10 .long __irq_invalid @ 6

11 .long __irq_invalid @ 7

12 .long __irq_invalid @ 8

13 .long __irq_invalid @ 9

14 .long __irq_invalid @ a15 .long __irq_invalid @ b16 .long __irq_invalid @ c17 .long __irq_invalid @ d18 .long __irq_invalid @ e19 .long __irq_invalid @ f

从第4行到第19行,记录了(代码链接阶段填入的地址数据)在各个模式下遇到irq中断时,发生异常的处理分支。比如第4行__irq_usr表示用户模式下发生irq中断时,由__irq_usr对应的代码段来处理这种情况。

vector_stub是一个宏,将宏展开内容如下:

vector_irq:

sub lr, lr, #4stmia sp, {r0, lr} @ save r0, lr

mrs lr, spsrstr lr, [sp, #8] @ save spsr

mrs r0, cpsr

eor r0, r0, #(IRQ_MODE ^ SVC_MODE)

msr spsr_cxsf, r0andlr, lr, #0x0fmovr0, sp

ldr lr, [pc, lr,lsl #2]

movs pc, lr @ branch to handlerinSVC mode

.endm

这个宏的目的就是,根据进入irq中断前处理器所处的模式,将紧接着其下边的16个地址池中对应位置的处理向量,取出来赋给PC,完成进一步跳转。这里我们选择让程序跳转到__irq_usr代码段继续执行。

3、异常处理进一步函数----__irq_usr

arch/arm/kernel/entry-armv.S

__irq_usr:usr_entry @将usr模式下的寄存器、中断返回地址保存到堆栈中

get_thread_info tsk @获取当前进程的进程描述符中的成员变量thread_info的地址,并将该地址保存到寄存器tsk等于r9

irq_handler @中断处理mov why, #0b ret_to_user@中断处理完成,返回中断产生的位置

4、irq_handler

irq_handler是一个宏,将其内容展开如下:

arch/arm/kernel/entry-armv.S

.macro irq_handler

get_irqnr_preamble r5, lr1: get_irqnr_and_base r0, r6, r5, lr

movne r1, sp

adrne lr, 1b

bne asm_do_IRQ

.endm

由此可见,进入asm_do_IRQ函数开始具体的中断处理。需要指出的是,asm_do_IRQ是中断的C语言总入口函数,到此为止中断处理汇编部分已经全部涉及到。具体的代码细节没有分析,主要是为了理清中断处理的整体脉络。

原文:http://www.cnblogs.com/amanlikethis/p/6921826.html

最后

以上就是感性火龙果为你收集整理的linux中断处理汇编入口,linux驱动之中断处理过程汇编部分的全部内容,希望文章能够帮你解决linux中断处理汇编入口,linux驱动之中断处理过程汇编部分所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部