ARM 아키텍처에서의 리눅스 인터럽트 처리 메커니즘

ARM 베어메탈 환경의 인터럽트 처리

S3C2440 기반 처리 예제:
.extern     main_func
.text 
.global _entry 
_entry:      
    b   SystemReset
UndefHandler:
    b   UndefHandler 
SwiHandler:
    b   SwiHandler
PrefetchHandler:
    b   PrefetchHandler
DataAbortHandler:
    b   DataAbortHandler
ReservedHandler:
    b   ReservedHandler
    b   IRQ_Entry
FIQHandler:
    b   FIQHandler

SystemReset:                  
    ldr stack_ptr, =0x1000
    bl  disable_watchdog
    
    msr cpsr_c, #0xd2
    ldr stack_ptr, =0xC00

    msr cpsr_c, #0xdf
    ldr stack_ptr, =0x1000

    bl  init_led_gpio
    bl  setup_irq
    msr cpsr_c, #0x5f
    
    ldr link_reg, =system_halt
    ldr pc, =main_func
system_halt:
    b   system_halt

IRQ_Entry:
    sub link_reg, link_reg, #4
    stmdb   stack_ptr!,    { reg0-reg12,link_reg }
    ldr link_reg, =isr_return
    ldr pc, =custom_isr
isr_return:
    ldmia   stack_ptr!,    { reg0-reg12,pc }^
인터럽트 발생 시 처리 단계:
  1. PC가 IRQ 벡터 주소로 설정되어 b IRQ_Entry 실행
  2. 링크 레지스터 조정 및 레지스터 저장
  3. ISR 함수(custom_isr) 실행
  4. SPSR 복원 및 작업 모드 복귀

리눅스 커널 인터럽트 처리 구조

벡터 테이블 (arch/arm/kernel/entry-armv.S):
.globl    __vectors_start
__vectors_start:
    swi    SYS_ERROR0
    b    undef_vector
    ldr    pc, .LCswi
    b    pabt_vector
    b    dabt_vector
    b    unused_vector
    b    irq_vector
    b    fiq_vector

IRQ 처리 매크로

.macro    vector_stub, mode, offset
\mode:
    sub    link_reg, link_reg, #4
    stmia    stack_ptr, {reg0, link_reg}    
    mrs    link_reg, spsr
    str    link_reg, [stack_ptr, #8]        
    mrs    reg0, cpsr
    eor    reg0, reg0, #(\mode ^ SVC_MODE)
    msr    spsr_cxsf, reg0
    and    link_reg, link_reg, #0x0f
    mov    reg0, stack_ptr
    ldr    link_reg, [pc, link_reg, lsl #2]
    movs    pc, link_reg
.endm

사용자 모드 인터럽트 진입점

__usr_irq:
    usr_entry
    get_thread_info tsk_reg
    irq_handler
    mov    status_reg, #0
    b    user_return

인터럽트 핸들러 디스패치

.macro    irq_dispatcher
    get_irqnr_start r5, lr
loop1:
    get_irq_number reg0, r6, r5, lr
    movne    reg1, stack_ptr
    adrne    lr, loop1
    bne    process_irq
.endm

플랫폼별 인터럽트 식별 (S3C2410)

.macro    get_irq_number, irqid, status, base, tmp
    mov    \base, #IRQ_BASE_ADDR
    ldr    \status, [ \base, #INT_PENDING ]
    ldr    \irqid, [ \base, #INT_OFFSET ]
    adds    \irqid, \irqid, #BASE_IRQ_NUM
.endm

인터럽트 번호 매핑: #define BASE_IRQ_NUM 16

태그: ARM 어셈블리 리눅스 커널 인터럽트 처리 벡터 테이블 asm_do_IRQ

7월 29일 18:11에 게시됨