Apple Exception Level (GXF)
소개
이 글은 https://blog.svenpeter.dev/posts/m1_sprr_gxf/ 글을 참고하여 정리한 글이다.
아사히 리눅스는 애플실리콘 맥에서 동작할 수 있도록 개발자들이 직접 리버싱을 통해 하드웨어 기능을 추가하는 리눅스 버전이다. 그래도 어느정도 기능이 지원되고 있기 때문에 코드를 참고해도 좋을 것 같다.
ARM의 익셉션 레벨
정상적으로 코드가 실행되다가 예외가 발생하면 CPU가 미리 정해진 예외 처리 코드로 제어를 넘기게된다.
min-os(x86)를 구현할때 CPU 입장에서는 인터럽트와 예외 모두 동일한 방식(Interrupt Descriptor Table)으로 처리되기도 하고, 인터럽트가 발생한 경우에도 ring(권한레벨, 익셉션레벨)이 변경되기 때문에 헷갈릴 순 있지만 사실은 명확히 구분이 되어야한다.
시스템콜은 syscall 명령이 호출될때 미리 커널에서 호출되어야하는 엔트리 함수를 등록하고 CS, SS 도 원하는 segment로 지정해둔 것이기 때문에 ring은 변하지만 IDT를 거치지 않는다.
ARM 에서는 현재 CPU가 실행중인 명령어 때문에 발생한 예외를 동기 예외라고 하고, 외부의 요인으로 발생한 예외를 비동기 예외라고 한다. 시스템콜과 인터럽트도 arm에서는 예외로 보기 때문에 Exception Level 이라는 이름이 붙었고 x86에서는 분류방식이 달라서 권한레벨 정도로만 생각하고 인터럽트와 예외가 분리되어 있는 구조이다.
ARM의 동기예외
- svc 실행 : arm에서는 시스템콜을 의도적인 예외(trap)로 본다.
- 정의되지 않은 명령 실행 : 아키텍쳐에서 유효하지 않은 명령을 의미한다. 데이터영역을 코드처럼 실행하거나 바이너리가 손상됐을때 발생한다.
- 권한없는 시스템 레지스터 접근 : EL0 코드가 EL1 이상의 레지스터에 접근하려 하면 예외가 발생한다. (특권명령 실행도)
- instruction abort : 가상주소가 매핑되지 않았거나 실행 권한이 없는 등 명령어를 읽을(fetch) 수 없을때 발생한다.
- data abort : 마찬가지로 load/store 중 권한이 없는 등의 문제가 발생했을때이다. null pointer dereference 도 여기에 포함된다.
- alignment fault : 메모리 접근, PC/SP 사용 시 아키텍쳐의 정렬 조건을 어겼을 때 발생할 수 있다.
- debug exception : breakpoint, watchpoint 등
ARM의 비동기 예외
- IRQ : 일반적인 외부 장치 인터럽트이다. CPU가 적절한 시점에 IRQ를 받아들여서 exception vector의 IRQ 엔트리로 들어가서 처리하게된다. 타이머가 만료됐거나 NIC가 패킷 수신을 완료하는 등 CPU가 처리할 이벤트가 생겼을때 통지하는 용도이다.
- FIQ : 예전 ARM에서는 빠른 인터럽트였는데, 지금은 IRQ와는 독립적인 경로(도착지 EL + Secure상태 + 코어)를 갖는 인터럽트일 뿐이다(우선순위도 동일함). 보통은 보안 상태나 소프트웨어 역할 분리를 위해 사용된다.
- SError : 시스템 에러를 말하는데, 외부 컨트롤러에서 에러가 발생 후 CPU에 보고할때 사용된다. 보통 메모리에서 MMU검사가 통과되고 버스 오류, ECC/패리티 등의 오류가 발생했을때 메모리 컨트롤러에서 CPU에 보고하기 때문에 명령어 실행 직후가 아니라 비동기적으로 전달되어 원인을 특정하기 어려운 시스템 오류이다.
예외 라우팅
예외는 현재 EL이나 더 높은 EL에서 처리되며 EL0 에서 처리되는 예외는 없다.
아키텍쳐가 target EL을 암묵적으로 설정해둔 경우나
Comments