Armv8 아키텍처에서 익셉션 레벨은 어떻게 변경될까요? 크게 3가지 방식으로 익셉션 레벨이 변경됩니다. 

 SVC, HVC, SMC 명령어 실행
 IRQ/FIQ 인터럽트 발생
 ERET 명령어 실행

다음 표를 보면 익셉션 레벨로 진입하는 방법을 확인할 수 있습니다. 

 

표 6.3 Armv8 아키텍처에서 익셉션 레벨로 진입하는 방법


먼저 유저 애플리케이션이 실행되는 EL0에서 진입되는 익셉션 레벨을 알아봅시다.

 

EL0에서 진입하는 익셉션 레벨


EL0에서 EL1으로 진입하는 방법은 크게 3가지로 분류할 수 있습니다. 

첫 번째로는 소프트웨어적으로 EL1에 진입하는 방법입니다. EL0에서 SVC 명령어를 실행하면 EL0 Synchronous 익셉션이 유발되면서 EL1으로 진입합니다. 이런 동작을 운영체제에서는 시스템 콜이라고 합니다. 

또한 EL0는 비특권 레벨(Unprivileged Level)로 실행되므로 시스템 메모리 공간에 직접 접근하거나 인터럽트와 같은 하드웨어를 설정하는 데 제약이 있어 시스템 콜을 통해 하드웨어 리소스에 접근할 수 있는 EL1으로 스위칭됩니다. 운영체제의 커널을 통해 시스템 리소스를 설정하는 방식입니다.

두 번째로는 메모리 어보트를 유발하는 명령어를 EL0에서 실행하면 EL0 Synchronous 익셉션이 유발되면서 EL1으로 진입합니다. 일반적으로 EL0에서 실행되는 유저 애플리케이션이 메모리 어보트를 유발하는 명령어를 실행하면 EL1으로 익셉션 레벨을 변경한 다음, 운영체제 커널은 해당 프로세스를 종료하는 동작을 수행합니다. 다른 관점으로 EL1으로 진입하는 두 번째 방식은 소프트웨어적으로 논리적인 오류가 있는 어셈블리 명령어를 실행하는 것입니다.

[정보] 메모리 어보트는 언제 유발될까?

NULL 포인터 익셉션을 유발하는 코드를 작성하면 메모리 어보트 타입 익셉션이 유발됩니다.


세 번째로는, EL0에서 소프트웨어 루틴이 실행되다가 'IRQ 인터럽트' 익셉션이 유발되면 EL1으로 진입합니다. 달리 말하면 EL0에서 유저 애플리케이션이 실행되다가 인터럽트가 발생하면 EL1으로 진입합니다. 세부 동작은 다음과 같이 분류할 수 있습니다.

1. EL0에서 유저 애플리케이션 실행
2. IRQ 인터럽트 익셉션이 유발됨
3. EL1으로 스위칭
4. EL1에 존재하는 익셉션 벡터 주소로 프로그램 카운터를 분기

여기까지 EL0에서 EL1으로 진입하는 3가지 방식을 알아봤습니다. 

 


[중요] EL0에서 EL1으로 진입하는 동작 방식과 디버깅
사실 실전 프로젝트에서 EL0에서 EL1으로 진입하는 동작 방식을 알면 유저 애플리케이션의 성능 이슈를 디버깅할 때 도움이 됩니다. 유저 애플리케이션을 구성하는 코드를 아무리 열심히  리뷰해도 그 원인을 파악하기가 어려운 상황에 종종 직면합니다. 이럴 때 다음과 같이 시스템 소프트웨어 관점으로 문제를 분석할 수 있습니다.

 

 

 시스템 콜이 발생한 횟수
 유저 애플리케이션이 실행되다가 인터럽트를 처리하는 횟수

또한 전체 소프트웨어 스택의 실행 흐름을 파악하려면 익셉션 레벨로 진입하는 방식을 잘 알면 좋습니다.

EL1에서 진입하는 익셉션 레벨

 

이번에는 EL1에서 EL2로 진입하는 방법을 알아봅시다. EL1에서 'HVC' 명령어를 실행하면 EL1에서 EL2로 진입합니다. EL1에서는 게스트 OS(운영체제 커널)가 구동되는데, 게스트 OS가 여러 게스트 OS의 리소스를 관리하는 하이퍼바이저에게 서비스를 요청할 때 EL2로 진입합니다.

이어서 EL1에서 시큐어 모니터 콜을 유발하는 'SMC' 명령어를 실행하면 EL3로 진입해 모니터 모드로 진입합니다. EL3 모니터 모드는 논 시큐어 상태에서 시큐어 상태로 이동할 때 문지기(게이트키퍼)와 같은 역할을 수행합니다.  

이번 절에서는 Armv8 아키텍처의 익셉션 레벨을 살펴봤습니다. 이어지는 절에서 익셉션 레벨과 관련된 레지스터에 대해 알아봅시다. 

 

< '시스템 소프트웨어 개발을 위한 Arm 아키텍처의 구조와 원리' 저자>
 
 

 

 

+ Recent posts