프리패치 어보트가 발생하는 전체 흐름을 살펴보면서, 세부 동작을 알아봅시다.

그림 8.7 프리페치 어보트 익셉션을 유발할 때 변경되는 레지스터
그림 8.7은 8.2 절에서 봤던 그림과 비슷해 보입니다. 한 가지 차이점은 그림의 가운데 부분과 같이 ARM 프로세서 내부에서 처리되는 동작을 슈도 코드로 표현한 것입니다. 슈도 코드는 하드웨어적으로 처리되는 과정에 대한 이해를 돕기 위해 작성된 것이란 사실을 기억합시다.
이해를 돕기 위해 프리패치 어보트가 발생한 명령어를 실행한 주소가 0xc000d000이라고 가정하겠습니다.
먼저 01번째 줄을 봅시다.
01 R14_abt = 0xc000d000 + 0x4
프리패치 어보트가 발생했으니 ARM 코어는 어보트 모드로 변경할 준비를 하는데, 먼저 어보트 모드에서만 사용되는 R14_abt 레지스터에 프리패치 어보트가 발생한 주소에 0x4를 더해 저장합니다. 프리패치 어보트가 발생한 코드의 주소가 0xc000d000이니 R14_abt 레지스터는 0xc000d004를 저장합니다.
프리페치 어보트는 파이프 라인 구조에서 페치 단계에서 발생합니다. 따라서 r14_abt 레지스터에는 익셉션이 발생한 명령어의 주소에 +4을 더한 주소가 저장됩니다. 파이프 라인에서 프리페치 어보트가 유발되는 세부 내용은 다음 포스트에서 참고하세요.
이어서 02번째 줄을 보겠습니다.
02 SPSR_abt= CPSR
SPSR_abt 레지스터에 프리패치 어보트가 발생한 시점의 CPSR 레지스터를 저장합니다.
만약 프리패치 어보트가 발생할 시점의 동작 모드가 슈퍼바이저 모드이면 CPSR 레지스터가 0x6000_0113이고, 이 때 SPSR_abt 레지스터는 0x6000_0113를 저장하게 됩니다.
다음으로 03번째 줄을 보겠습니다.
03 CPSR[4:0] = 10111
CPSR 레지스터의 [4:0] 비트를 이진수로 '10111'(16진수: 0x17)로 변경해 어보트 모드로 변경합니다. 프리패치 어보트가 발생할 시점에 CPSR 레지스터가 0x6000_0113이면, 이 시점에는 CPSR 레지스터가 0x6000_0117로 변경됩니다.
이어서 05~08번째 줄을 보겠습니다.
05 if high vector
06 PC = 0xffff_0000 + 0xC
07 else
08 PC = 0x0000_0000 + 0xC
06번째와 08번째 줄에 보이는 PC는 프로그램 카운터를 나타냅니다. 만약 익셉션 벡터 베이스 주소가 0xffff_0000으로 지정돼 있으면 06번째 줄, 0x0인 경우는 08번째 줄이 실행됩니다.
06번째 줄은 익셉션 벡터 베이스 주소인 0xffff_0000에 +0xC만큼 더해(오프셋을 적용) 프로그램 카운터에 지정하는 동작입니다. 마찬가지로 08번째 줄은 익셉션 벡터 베이스 주소인 0x0에서 +0xC만큼 더해(오프셋을 적용) 프로그램 카운터에 지정하는 동작을 나타냅니다.
이와 같은 동작은 ARM 코어에서 하드웨어적으로 처리됩니다.
Written by <디버깅을 통해 배우는 리눅스 커널의 구조와 원리> 저자

최근 덧글