[OS] 인터럽트

박성재·2021년 2월 21일
0

운영체제

목록 보기
8/10
post-thumbnail

패스트캠퍼스 컴퓨터 공학자 따라잡기 온라인 완주반
운영체제(이준희 님) 파트를 수강하며 공부한 내용을 정리한 자료입니다.

배너: godori님이 만드신 배너 메이커 활용


인터럽트란?

인터럽트 (Interrupt):
CPU가 프로그램을 실행하고 있을 때, 입출력 하드웨어 등의 장치에서 이슈나 예외 상황이 발생하여 처리가 필요할 경우에 CPU에 알려서 처리하는 기술

어느 한 순간 CPU가 실행하는 명령은 하나인데, 다른 장치와 어떻게 커뮤니케이션 하는 것일까?

인터럽트는 어떤 프로세스나 이벤트가 즉각적인 주의를 요할 때 하드웨어나 소프트웨어가 보내는 신호다.
인터럽트는 현재 수행중인 프로세스의 중단을 요하는, 우선순위가 높은 프로세스가 있음을 프로세서에게 알린다.

출처: https://www.geeksforgeeks.org/interrupts/

인터럽트가 필요한 이유

그림1. 프로세스 상태와 인터럽트

선점형 스케쥴러 구현

  • 프로세스 running 중에 스케쥴러가 이를 중단시키고 다른 프로세스로 교체하기 위해 현재 프로세스 실행을 중단시킨다.
  • 그러려면 스케쥴러 코드가 실행이 되어서 현 프로세스 실행을 중지시켜야 한다.

I/O Device 상황 핸들링

  • 저장매체에서 데이터 처리 완료 시, 이를 기다리고 있던 block 상태에 있는 프로세스를 꺠워야 한다. (block state -> ready state)

예외 상황 핸들링

  • CPU가 프로그램을 실행하고 있을 때 입출력 하드웨어 등의 장치에서 예외상황이 발생한 경우, CPU가 해당 처리를 할 수 있도록 CPU에게 알려줘야 한다. (장치 고장이나 비정상적 CPU 온도, 혹은 Division by Zero 예외 상황 등)

인터럽트 처리 예시

CPU가 프로그램을 실행하고 있을 때 입출력 하드웨어 등의 장치 이슈 발생

  • 파일 처리가 끝났다는 것을 운영체제에 알려주기
  • 운영체제는 해당 프로세스를 block state에서 실행 대기(ready) 상태로 프로세스 상태를 변경한다.

또는 예외 상황이 발생한 경우

  • 0으로 나누는 계산이 발생해서 예외 발생을 운영체제에 알려주기
  • 운영체제가 해당 프로세스 실행을 중지하고 에러 표시

이벤트와 인터럽트

  • 인터럽트는 일종의 이벤트로 불림
  • 각각의 이벤트에 맞게 운영체제가 처리

주요 인터럽트

Divide-by-Zero Interrupt

#include <stdio.h>

int main()
{
    printf("Hello World\n");
    int data;
    int divider = 0;
    data = 1 / divider;  // 이 부분에서 인터럽트 발생
    return 0;
}

위와 같은 코드를 실행하면 운영체제의 인터럽트 처리 루틴이 프로세스 실행을 중단하고 아래와 같은 에러를 표시한다.

Floating point exception (core dumped)

타이머 인터럽트

  • 선점형 스케쥴러를 위해 필요
  • 타이머 인터럽트를 발생시키는 칩이 컴퓨터에 별도로 존재
  • 이 칩에서 일정 시간마다 타이머 인터럽트를 운영체제에 알려줌

입출력(IO) 인터럽트

  • 키보드 인터럽트, 마우스 인터럽트, 프린터 인터럽트 등 입출력 장치의 동작 상태에 대해 알려주는 인터럽트

인터럽트 종류

내부 인터럽트

주요 프로그램 내부에서 잘못된 명령 또는 잘못된 데이터 사용 시 발생

  • 0으로 나눴을 때
  • 사용자 모드에서 허용되지 않은 명령 또는 공간 접근 시
  • 계산 결과가 Overflow/Underflow 날 때

내부 인터럽트는 주로 프로그램 내부에서 발생하므로, 소프트웨어 인터럽트라고도 함

외부 인터럽트

주로 하드웨어에서 발생되는 이벤트 (프로그램 외부)

  • 전원 이상
  • 기계 문제
  • 키보드 등 IO 관련 이벤트
  • Timer 이벤트

외부 인터럽트는 주로 하드웨어에서 발생하므로, 하드웨어 인터럽트라고도 함

인터럽트 내부 동작

시스템 콜 인터럽트

  • 시스템 콜 실행을 위해서는 강제로 코드에 인터럽트 명령을 넣어, CPU에게 실행시켜야 한다.
  • 시스템 콜 실제 코드
    • eax 레지스터에 시스템 콜 번호를 넣고,
    • ebx 레지스터에는 시스템 콜에 해당하는 인자값을 넣고,
    • 소프트웨어 인터럽트 명령을 호출하면서 0x80 값을 넘겨준다.
  mov eax, 1
  mov ebx, 0
  int 0x80 // 소프트웨어 인터럽트 명령

인터럽트와 시스템 콜

  • 시스템 콜 인터럽트 명령을 호출하면서 0x80 값을 넘겨준다.
    1. CPU는 사용자 모드를 커널 모드로 바꿔준다.
    2. IDT(Interrupt Descriptor Table)에서 0x80에 해당하는 주소(함수)를 찾아서 실행한다.
    3. system_call() 함수에서 eax로부터 시스템 콜 번호를 찾아서, 해당 번호에 맞는 시스템 콜 함수로 이동
    4. 해당 시스템 콜 함수 실행 후, 다시 커널 모드에서 사용자 모드로 변경하고, 다시 해당 프로세스에서 다음 코드 진행

인터럽트와 IDT

인터럽트는 미리 정의되어 각각 번호와 실행 코드를 가리키는 주소가 기록되어 있다.

  • 어디에? IDT(Interrupt Descriptor Table)
  • 언제? 컴퓨터 부팅 시 운영체제가 기록
  • 어떤 코드? 운영체제 내부 코드

위의 예를 다시 살펴보면,

  • 인터럽트 발생 시 IDT 확인
  • 시스템 콜 인터럽트 명령은 0x80 번호가 미리 정의
  • 인터럽트 0x80에 해당하는 운영체제 코드는 system_call()이라는 함수
  • 즉, IDT에는 0x80 -> system_call()과 같은 정보가 기록되어 있음

리눅스의 예

  • 0 ~ 31: 예외 상황 인터럽트 (일부는 정의되지 않은 채로 남겨져 있음)
  • 32 ~47: 하드웨어 인터럽트 (주변 장치 종류/개수에 따라 변경 가능)
  • 128: 시스템 콜

인터럽트와 프로세스

  1. 프로세스 실행 중 인터럽트 발생
  2. 프로세스 실행 중단
  3. 인터럽트 처리 함수 실행 (운영체제)
  4. 현 프로세스 재실행

그림2. 인터럽트와 프로세스

인터럽트와 스케쥴러

선점형 스케쥴러 구현 예시

수시로 타이머 인터럽트 발생

  • ex) 운영체제가 타이머 인터럽트 발생 횟수를 기억해서 타이머 인터럽트가 5번 발생하면 현재 프로세스를 다른 프로세스로 바꿔준다.

그림3. 타이머 인터럽트 예시

0개의 댓글