본문 바로가기
운영체제

9. 운영체제 - 인터럽트

by #Glacier 2020. 1. 3.
반응형

새해가 밝았네요.

후회가 많은 한 해.

 

이제 인터럽트에 대해서 공부해보겠습니다.

 

인터럽트란, CPU가 프로그램을 실행하고 있을 때,

입출력 하드웨어 등의 장치나 또는 예외상황이 발생하여 처리가 필요할 경우 CPU에 알려 처리하는 기술입니다.

 

인터럽트의 예시로, 우리가 이전에 공부했던 선점형 스케쥴러 구현이 좋은 예가 됩니다.

실행중인 프로세스를 중단시키고, 다른 프로세스를 CPU에서 동작시킬 때 인터럽트를 발생시키는 것입니다.

 

IO Device와 커뮤니케이션을 위해서 인터럽트가 필요하기도 합니다.

저장매체에서 데이터 처리 완료시, 프로세스를 깨워야 합니다. (block state 에서 ready state로)

그렇게 하기 위해서는 인터럽트가 필요한 것입니다.

 

또, 예외 상황을 핸들링 하는 경우에도 필요합니다.

CPU가 프로그램을 실행했을 때, 우리가 정의한 코드에서도 예외처리가 있는데, 

1 / 0 같은게 있을 수 있습니다. 0으로 나누는 것이 CPU에서 실행되면 CPU는 처리하려고 합니다.

그러나 0으로 나누는 것은 불가능합니다. (Divide-by-Zero Interrupt)

알 수 없기 때문에 이런 예외 상황을 핸들링 하기 위해 인터럽트가 필요합니다. (Process Kill)

 

즉, CPU가 프로그램을 실행하고 있을 때,

입출력 하드웨어 등의 장치 이슈가 발생하면 파일 처리가 끝났다는 것을 운영체제에 알리고,

운영체제는 해당 프로세스를 block state에서 ready state로 프로세스 상태를 변경합니다.

 

또는 예외 상황이 있을 때, 예외상황 발생을 운영체제에 알리고, 운영체제가 해당 프로세스 실행 중지와 함께

에러를 표시하게 됩니다.

 

인터럽트는 이렇게 일종의 이벤트라고 불리고, 이벤트에 맞게 운영체제가 처리하게 됩니다.

 

주요 인터럽트는 다음과 같습니다.

 

1) 0으로 나누는 계산 (Divide-by-Zero Interrupt)

2) 타이머 인터럽트 (선점형 스케쥴러를 위해 필요, 하드웨어로부터 일정 시간마다 타이머 인터럽트를 운영체제에 알림)

3) 입출력 (I/O) 인터럽트 (프린터, 키보드, 마우스, 저장매체) 키보드가 눌려있다, 프린트가 끝났다.. 등을 알림

 

인터럽트를 종류별로 나누면, 내부 인터럽트와 외부 인터럽트로 나눌 수 있습니다.

 

<내부 인터럽트>

 

- 프로그램 내부에서 잘못된 명령 또는 잘못된 데이터 사용 시 발생, 소프트웨어 인터럽트라고도 함

 

1) 0으로 나누는 계산

2) 사용자 모드에서 허용되지 않은 명령 또는 공간 접근시 (포인터의 주소가 잘못되었다던지...)

3) 계산 결과가 Overflow, Underflow 발생할 때

 

<외부 인터럽트>

 

- 주로 하드웨어에서 발생되는 이벤트 (프로그램 외부), 하드웨어 인터럽트라고도 함

 

1) 전원 이상

2) 기계 문제

3) 키보드 등 I/O 관련 이벤트

4) Timer 이벤트

 

시스템 콜도 인터럽트인데요, 시스템 콜 실행을 위해서는 강제로 코드에 인터럽트 명령을 넣어야 합니다.

실제 코드로는,

1) eax 레지스터에 시스템 콜 번호를 넣고,

2) ebx 레지스터에는 시스템 콜에 해당하는 인자값을 넣고,

3) 소프트웨어 인터럽트 명령을 호출하면서 0x80 값을 넘깁니다. (시스템 콜에 해당하는 인터럽트 번호)

4) CPU는 시스템 콜을 받으면 사용자 모드를 커널 모드로 바꿉니다.

5) IDT( Interrupt Descriptor Table )에서 0x80에 해당하는 주소(함수)를 찾아서 실행합니다.

6) system_call() 함수에서 eax로부터 시스템 콜 번호를 찾아서 해당 번호에 맞는 시스템콜 함수로 이동합니다.

7) 해당 시스템 콜 함수 실행 후, 다시 사용자 모드로 변경하고, 해당 프로세스로 다음 코드를 진행합니다.

 

마지막으로,

 

인터럽트는 미리 정의되어 각각 번호와 실행 코드를 가리키는 주소가 IDT(Interrupt Descriptor Table)에 기록되어 있습니다. 컴퓨터 부팅시에 운영체제가 기록하며, 운영체제 내부 코드로 기록됩니다.

 

인터럽트가 발생 시, IDT를 확인하며, 시스템콜 인터럽트 명령은 0x80번호가 미리 정의하고 있습니다.

인터럽트에 해당하는 운영체제 코드는 system_call()이라는 함수이며, 

IDT에는 0x80 -> system_call() 같은 정보가 기록되어 있습니다.

 

리눅스를 예로 들면, 다음과 같이 기록되어 있습니다.

  0~31 : 예외상황 인터럽트(일부는 정의되지 않은 채로 남겨져 있음, 내부 인터럽트, 소프트웨어 인터럽트)

32~67 : 하드웨어 인터럽트 (주변장치 종류, 갯수에 따라 변경 가능)

    128 : 시스템 콜 (0x80의 10진수)

 

다음 시간에는 프로세스 구조에 대해서 알아보겠습니다~

 

 출처 

이 글의 상당 부분은 패스트캠퍼스 컴퓨터 공학 기초 강의를 참고하였습니다.

개인 학습, 복기용이기 때문에 복제를 금합니다.

관심이 있으시다면 같이 공부하시거나, 해당 관련 강의를 직접 수강하시는 것을 추천합니다!

 

도움이 되시거나 더 좋은 지식을 공유하고 싶으시다면

아래의 댓글로 자유롭게 남겨주세요.

 

 

반응형