https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=goodkus&logNo=220214389063 

 

도전! 임베디드 OS만들기 - 4.1장(exception vector table 구성하기)

이번 장에서는 exception vector table을 공부합니다. exception vector table은 여러가지 인터럽트와 예외...

blog.naver.com

 

 

이번 장에서는 exception vector table을 공부합니다.

exception vector table은 여러가지 인터럽트와 예외를 처리할수 있는 주소를 모아놓은 테이블입니다.

 

먼저 예외와 동작모드에 관해서 보겠습니다.

 

arm에서의 예외는 총 7가지가 있습니다.

Data Abort : 메모리의 데이터를 읽거나 데이터를 쓰려다가 실패하는 경우 발생.

FIQ, IRQ : 외부 인터럽트가 코어에 전달될 때 발생.

Prefetch Abort : 명령어를 해석하다가 실패하는 경우 발생. 메모리에 존재하는 명령어를 읽어오다가 오류가 생기면 발생.

SWI(Software Interrupt) : 프로그램 내부에서 발생시키는 인터럽트. 소프트웨어 인터럽트라고 함. 시스템 콜의 핵심.

Reset : ARM 코어가 리셋되었을 경우 발생

Undefined Instruction : 읽어온 명령어가 ARM 코어와 코프로세서에 정의디지 않은 명령어일 때 발생.

 

OS나 임베디드 OS를 만들 경우엔 저 예외들은 필수로 들어간다고 생각합니다.

(현재 arm 아키텍쳐를 제일 많이 사용하니 보편적으로 사용하는 최소한의 예외라고 생각합시다.)

    

그리고 ARM에는 7가지 exception과 연결된 일곱가지의 프로세서 동작모드가 있습니다.

 

Abort(ABT)

Fast Interrupt Request(FIQ)

Interrupt Request(IRQ)

Supervisor(SVC)

System(SYS)

Undefined(UND)

USER(USR)

 

ABT, FIQ, IRQ, SVC, UND 모드는 exception이 발생할 때 자동으로 변경되는 동작모드,

SYS USR는 프로세서의 일반적인 동작 모드입니다.

 

예외 동작모드
Prefetch Abort ABT
Data Abort
FIQ FIQ
IRQ IRQ
Reset SVC
SWI
Undefined Undefined

 

예외가 발생할 경우 해당하는 동작모드로 변경을 하려면 cpsr(Current Program Status Register) 0~4번 비트를 수정해 주어야 합니다. 전에 3장에서 보았던 LED를 끄고 켤 때 관련된 레지스터의 비트를 수정하는 것과 같습니다.

 <!--[endif]--> 

모드 약자 특권기능 모드 비트(cpsr[4:0])
Abort abt yes 10111
FIQ fiq yes 10001
IRQ irq yes 10010
Supervisor svc yes 10011
System sys yes 11111
Undefined und yes 11011
USER usr no 10000

cpsr 0~4번 비트에 위의 표에서 나오는 모드 비트값을 넣으면 해당모드로 작동합니다.

근데 자세히보면 모드 비트의 자리수는 0~4번까지 5개의 비트를 사용합니다. 실제로 사용하는 모드는 총 7개뿐인데 말이죠.

방금 보았던 Prefetch Abort예외와 Data Abort예외가 Abort 동작모드에서 처리가 되도록 설정되었지만,

동작모드를 새로 하나 만들고 Prefetch Abort Data Abort를 각각 처리를 할수도 있다는 것을 유추해볼수 있습니다.

(2^5승이니 32.  32개까지 모드를 만들 수 있겠죠.)

 

책에서는 리눅스에서의 동작모드에 대해 엄청 잘 설명해놨습니다.

리눅스에서는 일반적으로 사용자 프로그램은 전부 다 USER모드에서 작동한다. 그러다가 프로그램 안에서 시스템 콜을 호출하면 프로그램은 SWI exception을 발생시키고, ARM 코어가 프로세서의 동작 모드를 SVC 모드로 변경시켜 Software Interrupt를 처리한 후에 다시 USER모드로 복귀한다. 마찬가지로 키보드 입력같은 경우는 대부분의 운영체제에서 IRQ로 처리한다. 우리가 키보드를 누르면 키보드 케이블을 통해 메인보드에 신호가 전달되고, 메인보드에 있는 여러 회로를 거쳐 ARM코어에 IRQ exception이 발생한다. 그러면 ARM 코어는 프로세서 동작 모드를 IRQ 모드로 변경하고 IRQ 관련 처리를 한 다음 USER모드로 복귀한다.”

 

근데 리눅스를 잘 사용하지 않아 조금 거부감이 있는 사람들을 위해 윈도우 측면에서 설명해 보겠습니다.

(왠만하면 위에껄로 이해하세요. 제가 설명하는게 정확한지 모릅니다.)

윈도우에서는 일반적으로 사용자 프로그램은 각각 생성된 윈도우 계정에서 작동한다.[USER모드에서 작동] 그렇게 프로그램에서 작업을 하던 중, 작업하던 프로그램이 멈춰버렸다. 응답이 없는 프로그램을 처리하기 위해서 우측 상단의 X표를 누른다.[SWI exception을 발생시킨다.] 그리고 예외를 처리하기 위해서 프로세서의 모드를 프로그램을 종료시킬수 있는 모드로 변경한다.[SVC 모드로 변경] 마지막으로 응답없는 프로그램을 종료 시키고[Software Interrupt 처리] 다시 프로그램이 켜지기 전의 상태로 돌아간다.[USER모드 복귀]

 

   

이제 예외를 처리하는 방법을 봅시다.

 

exception ARM에서 처리하는 순서.

1. exception이 발생함.

2. exception 모드의 spsr cpsr을 저장함.

3. exception 모드의 lr pc값을 저장함.

4. cpsr의 모드 비트를 변경하여, 해당 exception에 대응하는 프로세서 동작 모드로 진입함.

5. pc exception 핸들러의 주소를 저장하여 해당 exception에서 해야 할 일을 처리함.

 

spsr(Saved Program Status Register) : 각 동작모드에 존재하며, exception이 발생하여 cpsr을 변경해야 할 때 이전 모드의 cpsr spsr에 백업한다.

링크레지스터(lr) : exception의 처리후 복귀하기 위한 pc의 주소를 저장.

 

4번째에 보면 모드비트를 변경하고 나서, 대응하는 프로세서 동작 모드로 진입한다고 되어있습니다.

각 동작모드가 있는 주소를 모아 놓은 것이 exception vector table입니다.

감이 안잡힌다면 포인터 개념으로 생각하면 편합니다.

 

블로그 이미지

wtdsoul

,