1 min read

리눅스 커널 인터럽트 진입시 현재상태 저장

리눅스는 인터럽트 발생시 빠르게 레지스터값을 저장한다.

저장하는 함수는 __irq_svc이다.

이 코드는 어셈은 다음과 같다.

__irq_svc:
	svc_entry
	irq_handler

#ifdef CONFIG_PREEMPT
	ldr	r8, [tsk, #TI_PREEMPT]		@ get preempt count
	ldr	r0, [tsk, #TI_FLAGS]		@ get flags
	teq	r8, #0				@ if preempt count != 0
	movne	r0, #0				@ force flags to 0
	tst	r0, #_TIF_NEED_RESCHED
	blne	svc_preempt
#endif

https://github.com/raspberrypi/linux/blob/abaa3760da89d6fb38e55473fffc9a31dd0b1d7a/arch/arm/kernel/entry-armv.S#L206

좀 더 자세히 알아보기위해 어셈코드를 확인해보자.

커널을 빌드할때 심볼값인 System.map을 확인하자.

__irq_svc의 함수의 시작은 0xc0009940 이고 끝나는 지점은 0xc00099bc 알수 있다.

objdump --start-address=0xc0009940 --stop-address=0xc00099bc -d vmlinux

다음은 위 커맨드를 입력한 출력값이다.

c0009940 <__irq_svc>:
c0009940:       e24dd04c        sub     sp, sp, #76     ; 0x4c
c0009944:       e31d0004        tst     sp, #4
c0009948:       024dd004        subeq   sp, sp, #4
c000994c:       e88d1ffe        stm     sp, {r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip}
c0009950:       e8900038        ldm     r0, {r3, r4, r5}
c0009954:       e28d7030        add     r7, sp, #48     ; 0x30
c0009958:       e3e06000        mvn     r6, #0

다음은 stm명령어를 통해 레지스터값을 전부 스택에 저장한다.

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0204ik/Cihcadda.html

c000994c:       e88d1ffe        stm     sp, {r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip}