많은 소프트웨어 개발자는 예제 코드를 보면서 새로운 기능이나 개념을 배우는데, 이는 가장 효율적인 학습 방법 중 하나입니다. 대부분 코드의 구현부는 물론이고 사용 예시까지 분석합니다. 그런데 여러분들은 이전 절에서 설명된 익셉션의 구현 원리를 읽은 후 익셉션과 관련된 코드의 구현부가 무엇인지 의문을 품어 본 적이 있나요? 이번 절에서는 익셉션과 관련된 코드의 구현부에 대해서 살펴보겠습니다.
익셉션과 관련된 코드는 무엇일까
익셉션과 같은 ARM의 주요 기능을 공부할 때, 스스로 다음과 같이 질문을 던지면서 분석하면 더 많은 내용을 얻을 수 있습니다.
❑ 첫째, 해당 기능은 왜 알아야 할까?
❑ 둘째, 해당 기능은 어떤 코드로 구현됐을까?
다음 그림을 보면서 익셉션 관점에서 위에서 소개된 두 번째 질문에 대해 더 생각해볼까요?
그림 7.1 ARM 익셉션 기능 구현한 익셉션 벡터 핸들러의 위치
위 그림의 오른쪽 원에는 ARM 아키텍처가 있고 왼쪽 원에는 운영체제 커널이 있습니다. 두 원이 공통으로 만나는 부분은 ARM 아키텍처의 주요 기능이 구현된 부분을 나타내는데, 익셉션 관점으로는 익셉션 벡터 핸들러가 익셉션의 기능을 구현한 코드입니다.
달리 말하자면, 익셉션 벡터 핸들러와 익셉션 벡터 핸들러를 브랜치하는 주소의 위치가 바로 ARM 익셉션의 주요 기능이 구현된 실체라고 볼 수 있습니다.
익셉션 벡터 핸들러란
먼저 익셉션과 관련된 코드가 무엇인지 알아볼까요? 익셉션과 관련된 코드는 ARM 프로세서가 익셉션을 감지하면 실행되는 코드인데, 이를 익셉션 벡터 핸들러라고 말합니다. 익셉션 벡터 핸들러는 용어 그대로 익셉션을 핸들리(처리)하는 레이블이나 함수를 뜻합니다. 그렇다면 익셉션 벡터 핸들러의 코드는 어디에 위치해 있을까요? 바로 익셉션 벡터 주소입니다.
익셉션 벡터 주소와 익셉션 벡터 핸들러 코드 소개
다음 예제 코드를 보면서 익셉션 벡터 핸들러의 정체에 대해서 알아봅시다.
주소 명령어
01 0xffff0000 b reset_handler
02 0xffff0004 b undefined_inst_handler
03 0xffff0008 b sw_interrupt_handler
04 0xffff000c b prefetch_abort_handler
05 0xffff0010 b data_abort_handler
06 0xffff0014 b reserved_handler
07 0xffff0018 b irq_handler
08 0xffff0020 b fiq_handler
코드를 분석하기 전에 먼저 위에서 표기된 주소와 명령어에 대해서 알아봅시다.
먼저 왼쪽에 표시된 부분을 봅시다. 0xffff0000~0xffff0020 는 메모리 공간의 주소를 뜻합니다. 이어서 오른쪽 부분은 각 주소에서 실행되는 명령어입니다. 5번째 줄의 'b data_abort_handler' 명령어는 data_abort_handler 레이블로 브랜치하는 동작입니다. data_abort_handler 레이블로 브랜치를 하면 data_abort_handler 레이블이 실행됩니다.
또한 오른쪽에 ‘b’ 명령어 오른쪽에 보이는 01번째 줄의 reset_handler 부터 08번째 줄 까지 fiq_handler, 8개의 레이블을 익셉션 벡터 핸들러라고 합니다.
익셉션 벡터 핸들러 코드 분석
다음 절에 알아볼 예정이지만, ARM 프로세서는 익셉션을 감지하면 익셉션의 종류별로 지정된 주소로 프로그램 카운터를 브랜치합니다. 위 코드에서 0xffff0000 주소는 익셉션 벡터 테이블의 베이스 주소인데, 이 주소를 기준으로 익셉션의 종류별로 프로그램 카운터가 변경됩니다. 프로그램 카운터가 익셉션의 종류 별로 지정된 주소로 변경되면 해당 주소에 있는 익셉션 벡터 핸들러가 실행됩니다.
만약 어셈블리 명령어가 실행 중에 ARM 프로세서가 데이터 어보트와 같은 익셉션을 감지하면 익셉션 벡터 테이블의 베이스 주소 기준으로 +0x10 만큼 오프셋의 주소를 적용해 프로그램 카운터로 브랜치합니다. 즉, "0xffff0000 + 0x10"이란 공식에 따라 0xffff0010 주소로 프로그램 카운터가 바뀌는 것입니다.
0xffff0010 주소로 프로그램 카운터가 바뀌면, ARM 코어는 0xffff0010 주소에 있는 명령어인 'b data_abort_handler'를 패치해 실행하므로 data_abort_handler 레이블이 실행됩니다.
조금 어려운가요? 이번에는 다른 예를 들어 보겠습니다. 만약 외부 하드웨어에서 인터럽트가 발생하면 ARM 프로세서는 이를 인터럽트 익셉션을 유발해 "0xffff0000 + 0x18"이란 공식으로 0xffff0018 주소로 프로그램 카운터를 변경합니다. 마찬가지로 0xffff0018 주소로 프로그램 카운터가 바뀌면, ARM 코어는 0xffff0018 주소에 있는 명령어인 'b irq_handler'를 패치해 실행하므로 irq_handler 레이블이 실행됩니다.
코드 분석을 통해 배운 내용을 정리하면, "익셉션 벡터 핸들러의 코드는 익셉션 벡터의 베이스 주소에 위치한다"란 사실을 알 수 있습니다.
익셉션 벡터 핸들러는 어디에 구현돼 있을까?
하지만 의문은 여기서 끊나지 않습니다. "익셉션 벡터 핸들러는 유저 애플리케이션에 위치할까?" 혹은 "운영체제에 존재할까?"와 같은 궁금증이 생깁니다.
ARMv7 아키텍처에서 익셉션 벡터 핸들러의 구현부
다음 그림을 보면서 익셉션 벡터 핸들러가 어디에 구현됐는지 알아봅시다.
그림 7.2 ARMv7 아키텍처에서 익셉션 벡터 핸들러의 위치
그림의 윗 부분은 유저 애플리케이션이 실행되는 User 모드를 나타내고, 아랫 부분은 운영체제 커널이 실행되는 Supervisor 모드를 나타냅니다. 그런데 익셉션 벡터 핸들러는 운영체제 커널이 구동되는 Supervisor 모드에 위치합니다.
가장 대중적인 운영체제인 리눅스 커널을 기준으로 설명드리면 다음과 같은 코드가 리눅스 커널에 위치합니다.
주소 명령어
01 0xffff0000 b reset_handler
02 0xffff0004 b undefined_inst_handler
03 0xffff0008 b sw_interrupt_handler
04 0xffff000c b prefetch_abort_handler
05 0xffff0010 b data_abort_handler
06 0xffff0014 b reserved_handler
07 0xffff0018 b irq_handler
08 0xffff0020 b fiq_handler
정리하면, 익셉션이 발생했을 때 이를 처리하는 8개의 익셉션 벡터 핸들러는 익셉션 벡터의 베이스 주소에 위치합니다. 8개 익셉션 벡터 핸들러를 브랜치하는 0xffff0000~0xffff0020 주소의 코드가 운영체제의 커널이 구동되는 Supervisor 모드에 1벌이 있는 겁니다.
ARMv8 아키텍처에서 익셉션 벡터 핸들러의 구현부
이번에는 다음 그림을 보면서 ARMv8 아키텍처에서 익셉션 벡터 핸들러는 어디에 위치하는지 알아봅시다.

그림 7.3 ARMv8 아키텍처에서 익셉션 벡터 핸들러의 위치
ARMv7와 비교했을 때 ARMv8의 익셉션의 종류와 처리 방식은 다르나 기본 개념은 거의 같습니다.
그림 7.3의 윗 부분은 유저 애플리케이션이 실행되는 EL0(익셉션 레벨0)을 나타내고, 아랫 부분은 운영체제 커널이 실행되는 EL1를 나타냅니다. 익셉션 벡터 핸들러는 운영체제 커널이 구동되는 EL1 모드에 위치합니다.
ARMv7 아키텍처와 마찬가지로, ARMv8 아키텍처에서는 운영체제의 커널이 구동되는 EL1(Exception Level 1) 에서 익셉션 벡터 핸들러가 위치합니다.
익셉션 벡터 핸들러는 어느 이미지에 포함될까?
익셉션 벡터 핸들러는 운영체제의 커널이나 RTOS의 커널 이미지에 포함돼 있습니다. 리눅스 운영체제의 기준으로 보면, 리눅스 커널 이미지에 익셉션 벡터의 코드가 포함돼 있다고 볼 수 있습니다.
익셉션 벡터 핸들러의 코드가 "구체적으로 어디에 위치하는지", "어느 이미지에 포함되는지"는 실전 소프트웨어 개발자 입장에서 알아야 할 핵심 정보입니다. 이 내용은 익셉션 벡터 테이블을 설명할 때 자세히 살펴볼 예정입니다.
익셉션을 배울 때 먼저 기본 개념과 기능을 익힌 다음에 추가 기능으로 확장해 배우는 게 가장 효율적인 방법이라 생각합니다. 그래서 이번 절에서 설명드린 익셉션 벡터 핸들러의 위치는 하이퍼바이저나 트러스트 존이 구현이 안된 기본 기능으로 구성된 시스템 기준으로 설명드렸습니다. 만약 여러분이 개발하는 시스템이 하이퍼바이저 기반 아키텍처이거나 혹은 트러스트 존이 구현된 시스템인 경우 익셉션 벡터 핸들러가 추가로 구현돼야 합니다.
이 내용은 나중에 포스팅될 트러스트 존과 하이퍼바이저 포스팅에서 확인할 수 있습니다.
---
"이 포스팅이 유익하다고 생각되시면 공감 혹은 댓글로 응원해주시면 감사하겠습니다.
"혹시 궁금한 점이 있으면 댓글로 질문 남겨주세요. 아는 한 성실히 답변 올려드리겠습니다!"
Thanks,
Guillermo Austin Kim(austindh.kim@gmail.com)
---
Reference: ARM 프로세서 익셉션 소개
익셉션이란?
익셉션의 주요 개념
❑ 익셉션의 타입 소개
익셉션과 같이 배워야 하는 운영체제 지식
Written by <디버깅을 통해 배우는 리눅스 커널의 구조와 원리> 저자
최근 덧글