Arm Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

8179
1390
307630


[라즈베리파이] 인터럽트 백터 - 스택 푸쉬 5. 인터럽트

#리눅스 커널: 인터럽트


인터럽트가 발생했을 때 구동중인 프로세스의 레지스터가 스택 메모리 공간에 푸쉬된다고 설명했는데요. 실제 Trace32 프로그램으로 스택 메모리 덤프를 확인해 보겠습니다.

 

아래 콜스택은 리눅스 커널에서자주 볼 수 함수로 구성되어 있는데 ext4 파일 시스템에서 특정 파일을 동기화(Synch)하는 동작 중에 인터럽트가 발생했습니다..
-000|account_group_exec_runtime(inline)
-000|update_curr()
-001|check_spread(inline)
-001|put_prev_entity()
-002|put_prev_task_fair()
-003|pick_next_task_rt(inline)
-003|pick_next_task_rt()
-004|pick_next_task(inline)
-004|__schedule()
-005|arch_local_irq_disable(inline)
-005|preempt_schedule_irq()
-006|svc_preempt(asm)
-007|__irq_svc(asm)
 -->|exception
-008|blk_flush_plug_list()
-009|current_thread_info(inline)
-009|blk_finish_plug()
-010|ext4_writepages()
-011|__filemap_fdatawrite_range()
-012|filemap_write_and_wait_range()
-013|ext4_sync_file()
-014|vfs_fsync()
-015|fdput(inline)
-015|do_fsync()
-016|ret_fast_syscall(asm)

그럼 위 콜스택에서 인터럽트 벡터인 __irq_svc 함수가 호출된 시점의 스택 덤프를 확인하면
아래 화살표와 같이 스택에 푸쉬된 레지스터를 확인할 수 있습니다. 
________address||value_______|symbol
NSD:CE4F9D80| 0x20070013
NSD:CE4F9D84| 0xFFFFFFFF   
NSD:CE4F9D88| 0xCE4F9DE4
NSD:CE4F9D8C| 0xC0FF97B4   \\vmlinux\Global\__irq_svc+0x74
NSD:CE4F9D90| 0xCE4F8000
NSD:CE4F9D94| 0xCE4F8000
NSD:CE4F9D98| 0xCE4F9DAC
NSD:CE4F9D9C| 0xC0FF4E2C   \\vmlinux\sched/core\preempt_schedule_irq+0x50
NSD:CE4F9DA0| 0xC039B9DC   \\vmlinux\blk-core\blk_flush_plug_list+0x1A4
NSD:CE4F9DA4| 0xC039B9E0   \\vmlinux\blk-core\blk_flush_plug_list+0x1A8
NSD:CE4F9DA8| 0x1           
NSD:CE4F9DAC| 0xC0FF97D8   \\vmlinux\Global\svc_preempt+0x8
NSD:CE4F9DB0| 0x0           // <--[1] R0
NSD:CE4F9DB4| 0xCECC72B4   // <--[2] R1
NSD:CE4F9DB8| 0x1           // <--[3] R2
NSD:CE4F9DBC| 0x0           // <--[4] R3
NSD:CE4F9DC0| 0xCE4F9E00   // <--[5] R4
NSD:CE4F9DC4| 0xEAD60A60   // <--[6] R5
NSD:CE4F9DC8| 0x1           // <--[7] R6
NSD:CE4F9DCC| 0xCE4F9E00   // <--[8] R7 
NSD:CE4F9DD0| 0x0            // <--[9] R8
NSD:CE4F9DD4| 0x60070013   // <--[10] R9
NSD:CE4F9DD8| 0xCE4F8000   // <--[11] R10
NSD:CE4F9DDC| 0x1           // <--[12] R11
NSD:CE4F9DE0| 0x60070093   // <--[13] R12
NSD:CE4F9DE4| 0xCE4F9E00  // <--[14] R13, 스택 주소
NSD:CE4F9DE8| 0xC039B9DC \\vmlinux\blk-core\blk_flush_plug_list+0x1A4//<--[15]R14
NSD:CE4F9DEC| 0xC039B9E0   \\vmlinux\blk-core\blk_flush_plug_list+0x1A8 //<--[16]PC
NSD:CE4F9DF0| 0x20070013
NSD:CE4F9DF4| 0xFFFFFFFF

리눅스 커널 이론서를 보면 “인터럽트가 발생하면 프로세스에서 돌고 있는 정보를 저장한다”는 내용을 수없이 읽었는데 전 머리에 잘 남지 않더라고요. 실제 메모리 덤프를 확인하고 나서 정확히 이해하게 되었습니다.


덧글

댓글 입력 영역