처음 익셉션 벡터 테이블을 분석하면 다음과 같은 의문이 생기는 경우가 많습니다.


"이와 관련된 코드는 어디에 구현돼 있을까?"
이 질문에 답을 하려면 익셉션 벡터와 관련된 코드가 무엇인지 알아야 하는데, 이를 익셉션 벡터 핸들러라고 합니다. 익셉션 벡터 핸들러는 익셉션의 종류 별로 소프트웨어적으로 처리되는 목적의 명령어로 구성돼 있는데 익셉션 벡터 주소에서 브랜치됩니다.
익셉션 핸들러 코드 분석하기
이제부터 오픈 소스 기반의 운영체제인 리눅스 커널에서 확인된 익셉션 벡터와 익셉션 백터 핸들러의 코드를 보면서 배운 내용을 다져봅시다. 다음은 익셉션 벡터와 익셉션 핸들러를 브랜치하는 코드입니다.
01 ffff0000: ea0003ff b 0xffff1004 <vector_rst>
02 ffff0004: ea000465 b 0xffff11a0 <vector_und>
03 ffff0008: e59ffff0 ldr pc, [pc, #4080] ; 0xffff1000 // <vector_swi>
04 ffff000c: ea000443 b 0xffff1120 <vector_pabt>
05 ffff0010: ea000422 b 0xffff10a0 <vector_dabt>
06 ffff0014: ea000481 b 0xffff1220 <vector_addrexcptn>
07 ffff0018: ea000400 b 0xffff1020 <vector_irq>
08 ffff001c: ea000487 b 0xffff1240 <vector_fiq>
리눅스 커널에서는 익셉션 벡터 테이블의 베이스 주소를 ffff0000로 지정합니다. 그렇다면 위 코드에서 익셉션 벡터는 무엇일까요? ffff0000~ffff001c 구간의 주소가 익셉션 벡터이며, 4바이트 단위로 정렬된 것을 볼 수 있습니다.
위 코드를 ARM 아키텍처 관점으로 다음과 같이 설명할 수 있습니다.
"ARM 코어가 익셉션을 유발하면 ffff0000~ffff001c 구간의 주소로
프로그램 카운터를 브랜치한다."
물론 이 동작은 ARM 코어에서 하드웨어적으로 처리됩니다.
이번에는 메모리 어보트 타입 익셉션이 발생하면 어느 익셉션 벡터로 프로그램 카운터가 브랜치되는지 알아봅시다. 먼저 다음은 익셉션 벡터 테이블에서 봤던 오프셋 주소 정보입니다.
* Undefined Instruction: +0x04(0xffff_0004)
* 프리페치 어보트: +0x0C(0xffff_000C)
* 데이터 어보트: +0x10(0xffff_0010)
메모리 어보트 타입 익셉션이 발생하면 어느 익셉션 벡터로 프로그램 카운터가 브랜치되는지 알아봅시다.
Undefined Instruction 익셉션이 유발되면, 익셉션 벡터 베이스 주소(0xffff_0000)에서 오프셋인 0x04를 더해 0xffff_0004 주소로 프로그램 카운터가 브랜치됩니다. 프리페치 어보트와 데이터 어보트도 같은 규칙에 따라, 0xffff_000C, 0xffff_0010 주소로 프로그램 카운터가 브랜치됩니다.
그런데 ARM 코어가 프로그램 카운터를 특정 주소로 브랜치하면 해당 주소에 위치한 명령어가 실행됩니다. 즉, 익셉션의 종류 별로 다음과 같은 어셈블리 명령어가 실행됩니다.
* Undefined Instruction: "b vector_und"(0xffff_0004)
* 프리페치 어보트: "b vector_pabt" (0xffff_000C)
* 데이터 어보트: "b vector_dabt" (0xffff_0010)
ARM 어셈블리 명령어로 ‘b’는 지정한 주소나 레이블로 브랜치하는 동작입니다. “b vector_und” 명령어가 실행되면 vector_und이란 레이블로 브랜치됩니다. 프리페치 어보트와 데이터 어보트도 같은 원리로 ‘vector_pabt’와 ‘vector_dabt’ 레이블로 브랜치됩니다.
익셉션 벡터와 익셉션 핸들러를 브랜치하는 코드 분석하기
이번에는 익셉션의 종류별로 익셉션 벡터와 해당 익셉션 벡터에 위치한 코드를 표로 정리해봅시다.

표 8.5 익셉션 벡터와 익셉션 핸들러
표 8.5와 같이 익셉션 벡터를 처리할 수 있는 주소 공간이 4바이트이므로, 익셉션 벡터 주소에는 vector_rst부터 vector_fiq까지 익셉션의 종류 별로 처리하는 레이블을 브랜치하는 코드로 구성돼 있습니다. 사실 익셉션의 종류 별로 후속 처리하기 위해서는 다양한 명령어가 수행되야 하는데, 해당 코드는 vector_rst부터 vector_fiq 레이블에 위치해 있습니다.
Written by <디버깅을 통해 배우는 리눅스 커널의 구조와 원리> 저자

최근 덧글