新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > linux-2.6.26內(nèi)核中ARM中斷實(shí)現(xiàn)詳解

linux-2.6.26內(nèi)核中ARM中斷實(shí)現(xiàn)詳解

作者: 時(shí)間:2012-09-01 來源:網(wǎng)絡(luò) 收藏

三、中斷處理過程

這一節(jié)將以S3C2410為例,描述-2.6.26中,從中斷開始,中斷是如何一步一步執(zhí)行到我們注冊(cè)函數(shù)的。

3.1 中斷向量表 archarmkernelentry-armv.S

__vectors_STart:

swi SYS_ERROR0

b vector_und + stubs_offset

ldr pc, .LCvswi + stubs_offset

b vector_pa^ + stubs_offset

b vector_da^ + stubs_offset

b vector_addrexcptn + stubs_offset

b vector_IRq + stubs_offset

b vector_fiq + stubs_offset

.globl __vectors_end

__vectors_end:

中斷發(fā)生后,跳轉(zhuǎn)到b vector_irq + stubs_offset的位置執(zhí)行。注意現(xiàn)在的向量表的初始位置是0xffff0000。

3.2 中斷跳轉(zhuǎn)的入口位置 archarmkernelentry-armv.S

.globl __stubs_start

__stubs_start:

/*

* Interrupt dispatcher

*/

vector_stub irq, IRQ_MODE, 4 @IRQ_MODE在includeasmptrace.h中定義:0x12

.lONg __irq_usr @ 0 (USR_26 / USR_32)

.long __irq_invalid @ 1 (FIQ_26 / FIQ_32)

.long __irq_invalid @ 2 (IRQ_26 / IRQ_32)

.long __irq_svc @ 3 (SVC_26 / SVC_32)

.long __irq_invalid @ 4

.long __irq_invalid @ 5

.long __irq_invalid @ 6

.long __irq_invalid @ 7

.long __irq_invalid @ 8

.long __irq_invalid @ 9

.long __irq_invalid @ a

.long __irq_invalid @ b

.long __irq_invalid @ c

.long __irq_invalid @ d

.long __irq_invalid @ e

.long __irq_invalid @ f

上面代碼中vector_stub宏的定義為:

.macro vector_stub, name, mode, correcTIon=0

.align 5

vector_nAME:

.if correction

sub lr, lr, #correction

.endif

@

@ Save r0, lr_ (parent PC) and spsr_

@ (parent CPSR)

@

stmia sp, {r0, lr} @ save r0, lr

mrs lr, spsr

str lr, [sp, #8] @ save spsr

@

@ Prepare for SVC32 mode. IRQs remain disabled.

@

mrs r0, cpsr

eor r0, r0, #(mode ^ SVC_MODE)

msr spsr_cxsf, r0 @為后面進(jìn)入svc模式做準(zhǔn)備

@

@ the branch table must immediately follow this code

@

and lr, lr, #0x0f @進(jìn)入中斷前的mode的后4位

@#define USR_MODE 0x00000010

@#define FIQ_MODE 0x00000011

@#define IRQ_MODE 0x00000012

@#define SVC_MODE 0x00000013

@#define ABT_MODE 0x00000017

@#define UND_MODE 0x0000001b

@#define SYSTEM_MODE 0x0000001f

mov r0, sp

ldr lr, [pc, lr, lsl #2] @如果進(jìn)入中斷前是usr,則取出PC+4*0的內(nèi)容,即__irq_usr @如果進(jìn)入中斷前是svc,則取出PC+4*3的內(nèi)容,即__irq_svc

movs pc, lr @ 當(dāng)指令的目標(biāo)寄存器是PC,且指令以S結(jié)束,則它會(huì)把@ spsr的值恢復(fù)給cpsr branch to handler in SVC mode

.endm

.globl __stubs_start

__stubs_start:

/*

* Interrupt dispatcher

*/

vector_stub irq, IRQ_MODE, 4

.long __irq_usr @ 0 (USR_26 / USR_32)

.long __irq_invalid @ 1 (FIQ_26 / FIQ_32)

.long __irq_invalid @ 2 (IRQ_26 / IRQ_32)

.long __irq_svc @ 3 (SVC_26 / SVC_32)

用“irq, IRQ_MODE, 4”代替宏vector_stub中的“name, mode, correction”,找到了我們中斷處理的入口位置為vector_irq(宏里面的vector_name)。

從上面代碼中的注釋可以看出,根據(jù)進(jìn)入中斷前的工作模式不同,程序下一步將跳轉(zhuǎn)到_irq_usr 、或__irq_svc等位置。我們先選擇__irq_usr作為下一步跟蹤的目標(biāo)。

3.3 __irq_usr的實(shí)現(xiàn) archarmkernelentry-armv.S

__irq_usr:

usr_entry @后面有解釋

kuser_cmpxchg_check

#ifdef CONFIG_TRACE_IRQFLAGS

bl trace_hardirqs_off

#endif

get_thread_info tsk @獲取當(dāng)前進(jìn)程的進(jìn)程描述符中的成員變量thread_info的地址,并將該地址保存到寄存器tsk等于r9(在entry-header.S中定義)

#ifdef CONFIG_PREEMPT//如果定義了搶占,增加搶占數(shù)值

ldr r8, [tsk, #TI_PREEMPT] @ get preempt count

add r7, r8, #1 @ increment it

str r7, [tsk, #TI_PREEMPT]

#endif

irq_handler @中斷處理,我們最關(guān)心的地方,3.4節(jié)有實(shí)現(xiàn)過程。

#ifdef CONFIG_PREEMPT

ldr r0, [tsk, #TI_PREEMPT]

str r8, [tsk, #TI_PREEMPT]

teq r0, r7

strne r0, [r0, -r0]

#endif

#ifdef CONFIG_TRACE_IRQFLAGS

bl trace_hardirqs_on

#endif

mov why, #0

b ret_to_user @中斷處理完成,返回中斷產(chǎn)生的位置,3.7節(jié)有實(shí)現(xiàn)過程

上面代碼中的usr_entry是一個(gè)宏,主要實(shí)現(xiàn)了將usr模式下的寄存器、中斷返回地址保存到堆棧中。

.macro usr_entry

sub sp, sp, #S_frame_SIZE @ S_FRAME_SIZE的值在archarmkernelasm-offsets.c

@ 中定義 DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));實(shí)際上等于72

stmib sp, {r1 - r12}

ldmia r0, {r1 - r3}

add r0, sp, #S_PC @ here for interlock avoidance

mov r4, #-1 @ "" "" "" ""

str r1, [sp] @ save the "real" r0 copied

@ from the exception stack

@

@ We are now ready to fill in the remaining blanks on the stack:

linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)


關(guān)鍵詞: linux 內(nèi)核 ARM中斷

評(píng)論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉