본문 바로가기
운영체제

컴퓨터 구조 : CPU 인터럽트(Interrupt) 와 인터럽트 핸들링

by oobw 2023. 10. 20.

1. 인터럽트(Interrupt) 란?

컴퓨터 시스템에서 중앙 처리 장치(CPU)는 가장 바쁜 핵심 작업 처리자입니다. 인터럽트는 이런 CPU에게 현재 수행 중인 작업을 일시 중지하고 다른 작업(긴급한 작업)을 수행하도록 하는 신호나 메커니즘을 말합니다. 쉽게 말하면, 인터럽트는 CPU에게 "잠시 멈추고 이것을 처리해!"라고 말하는 것과 같습니다.

 

CPU에 요청이 필요한 모든 서브시스템들은 CPU에게 인터럽트를 발생시킵니다. 하드웨어 장치들은 자신의 상태 변경이나 데이터 준비 상태를 CPU에 알려야 할 때가 있습니다. 이때 인터럽트를 사용하여 CPU에게 해당 사항을 통지하게 됩니다. 즉, 인터럽트를 통해 서브시스템들은 CPU에게 제어 신호나 상태 신호를 보낼 수 있습니다.

 

CPU는 이런 인터럽트를 받아서 서브시스템들에 대한 상태를 알 수도 있고, 오류 및 예외 처리가 발생했을 때 인지할 수 있습니다. 프로그램이 잘못된 명령을 실행하거나 예기치 않은 오류가 발생할 경우, 인터럽트 메커니즘이 해당 오류를 CPU에 알리고 CPU는 이에 따라 적절한 조치를 취할 수 있도록 합니다.

 

컴퓨터 시스템의 작동 원리에서 인터럽트의 역할은 중요합니다. 인터럽트 덕분에 현대 컴퓨터는 다양한 작업을 동시에 처리할 수 있습니다. 또한, 인터럽트 메커니즘을 통해 CPU는 긴급하거나 우선순위가 높은 작업을 즉시 처리할 수 있어 사용자나 다른 시스템 요청에 대한 응답 시간이 개선됩니다.

2. 인터럽트의 유형

인터럽트는 그 발생 원인과 처리 방식에 따라 다양한 유형으로 분류될 수 있습니다. 이러한 인터럽트들은 컴퓨터 시스템이 효율적으로 작동할 수 있도록 도와주며, 상황에 따라 적절한 응답과 대처를 가능하게 합니다. 인터럽트는 I/O 하위 시스템, CPU 또는 소프트웨어에 의해 생성됩니다.

 

하드웨어 인터럽트: 외부 I/O 인터럽트

하드웨어 인터럽트는 주로 외부 장치나 하드웨어 컴포넌트로부터 발생합니다. 이는 특정 장치의 상태 변화나 데이터 전송 요청과 같은 하드웨어 이벤트에 의해 발생하는데, 예를 들어 키보드의 키 입력이나 하드 드라이브의 데이터 전송 완료와 같은 이벤트가 이에 해당합니다.

하드웨어 인터럽트: 내부 인터럽트

프로그램의 실행 도중 예상치 못한 상황에서 발생하는 인터럽트를 말합니다. 프로그램의 오류나 예기치 않은 상황, 예를 들면 잘못된 메모리 접근이나 오버플로와 같은 상황에서 시스템은 예외를 발생시켜 이러한 문제를 알리게 됩니다.

소프트웨어 인터럽트

소프트웨어 인터럽트는 프로그램의 실행 과정 중 발생하는 인터럽트로, 프로그램이 운영체제의 특정 서비스를 요청하거나 특별한 상황에서 발생합니다. 시스템 호출이나 예외 처리 요청은 이 유형의 대표적인 예시입니다.

 

이렇게 다양한 인터럽트 유형을 통해 시스템은 다양한 상황에 빠르게 대응하며, 사용자의 요청이나 하드웨어의 상태 변화에 신속하게 응답할 수 있게 됩니다.

3. 인터럽트의 작동 원리: 인터럽트 서비스 루틴

인터럽트의 작동 원리를 이해하기 위해서는 인터럽트의 요청 과정과 인터럽트 서비스 루틴(ISR)에 대한 개념을 알아야 합니다.

인터럽트 요청 과정

외부 장치나 프로그램에서 어떤 특정 이벤트나 상태 변화가 발생했을 때, 그것을 CPU에게 알리기 위해 인터럽트를 발생시킵니다. CPU는 이러한 요청을 받아들이고, 현재 실행 중인 작업을 잠시 멈추게 됩니다. 이때, CPU는 현재까지의 작업 상태를 메모리에 저장하여 나중에 이어서 수행할 수 있게 합니다.

하지만 모든 인터럽트 요청이 즉시 처리되는 것은 아닙니다. 시스템 내에서 인터럽트에는 다양한 우선 순위가 있으며, 이 우선순위에 따라 CPU는 인터럽트 요청을 처리하게 됩니다. 예를 들어, 긴급하게 처리해야 하는 인터럽트와 그렇지 않은 인터럽트가 동시에 발생한다면, CPU는 더 높은 우선순위를 가진 인터럽트를 먼저 처리하게 됩니다.

인터럽트 서비스 루틴 (Interrupt Service Routine: ISR)

인터럽트 서비스 루틴(ISR)은 특정 인터럽트가 발생했을 때 실행되는 프로그램 코드를 의미합니다. 인터럽트 요청이 인지되면, CPU는 해당 인터럽트에 대응하는 ISR을 실행하게 됩니다. ISR은 인터럽트의 원인을 파악하고, 필요한 조치를 취한 뒤, CPU에게 원래의 작업으로 돌아갈 수 있도록 지시합니다.

예를 들어, 키보드에서 키 입력이 발생했을 때 이를 CPU에 알리는 인터럽트가 발생하면, 키 입력 처리를 위한 ISR이 실행되어 키 입력 정보를 가져오고, 이 정보를 적절한 메모리 위치에 저장합니다. ISR의 작업이 끝나면 CPU는 원래의 작업으로 돌아가게 됩니다.

요약하면, 인터럽트는 CPU가 다양한 작업을 효과적으로 동시에 처리할 수 있도록 돕는 메커니즘입니다. 인터럽트 요청 과정을 통해 CPU는 중요한 작업에 대해 즉시 반응하며, ISR을 통해 인터럽트의 원인을 파악하고 적절한 조치를 취하게 됩니다.

 

아래 그림은 이 과정을 4단계로 표현하고 있습니다.

 

  • 먼저 CPU가 주 프로그램을 순차적으로 수행하는 도중에 서브시스템이 인터럽트를 발생시킵니다.
  • CPU는 현재 수행 중인 명령(N)을 수행한 후에 이를 인지하게 됩니다.
  • CPU는 순차적으로 다음 명령(N+1)을 수행하는 것이 아니라, 실행 흐름 제어는 해당 인터럽트 서비스 루틴으로 변경합니다.
  • 인터럽트 서비스 루틴에서 가장 먼저 하는 동작은  프로세서의 컨텍스트 전환입니다. 이 부분은 모든 종류의 인터럽트에 공통적으로 적용됩니다.
  • 이어서 인터럽트 서비스 루틴에 구현된 명령어를 수행합니다. 이 루틴은 인터럽트 서비스 루틴에 따라 다르게 구현되어 있습니다.
  • 예를 들어 산술 오버플로우 오류가 발생하면 인터럽트 서비스 루틴은 사용자에게 오류를 알리는 메시지를 보내고 프로그램을 종료할 수 있습니다. 페이지 폴트가 발생하면 페이지 교환이 발생합니다.
  • 인터럽트 서비스 루틴이 완료되면 위 그림에서 보여지는 것처럼 원래 프로세서의 컨택스트를 복구하고 실행 흐름이 중단된 지점 (N+1)부터 다시 시작됩니다.

4. 인터럽트 우선순위 및 식별

시스템에서는 여러 I/O 컨트롤러가 동시에 인터럽트를 발생시킬 수 있습니다. 이러한 상황에서는 CPU가 어떤 인터럽트를 먼저 처리해야 할지, 즉 인터럽트의 우선순위를 어떻게 판별할지가 중요한 문제가 됩니다.

 

데이지 체이닝(Daisy Chaining)

여러 I/O 컨트롤러 중에서 인터럽트의 우선순위는 하드웨어적으로 정해져 있습니다. 우선순위가 높은 인터럽트가 먼저 처리되며, 이를 위해 데이지 체이닝 방식이 사용될 수 있습니다. 이 방식에서는 보통 저속의 장치 컨트롤러가 더 낮은 우선순위를 갖게 되며, 우선순위에 따라 인터럽트가 순차적으로 처리됩니다.

식별 방법

  • 폴링: 이는 소프트웨어적인 방법으로, ISR이 인터럽트 원인을 파악하기 위해 여러 상태 레지스터를 차례대로 확인하는 방식입니다.
  • 벡터 인터럽트: 특정 인터럽트를 식별하기 위해 CPU와 I/O 사이에 추가 신호 라인이 도입됩니다. 각 I/O 컨트롤러는 고유한 INT CODE를 가지며, 이 코드는 인터럽트의 유형을 나타내고, ISR의 위치를 찾는 데 사용됩니다.

중첩 인터럽트

동시에 여러 인터럽트가 발생하는 경우, 시스템은 이를 효과적으로 관리해야 합니다. 이때 중첩 인터럽트 방식을 사용할 수 있으며, 이는 ISR 처리 도중 다른 인터럽트가 발생했을 때, 그 인터럽트를 즉시 처리할 것인지, 아니면 일단 보류할 것인지를 결정하는 방법입니다.

5. 인터럽트 서비스 루틴의 식별: 인터럽트 벡터 테이블

다양한 장치가 CPU에게 인터럽트 신호를 보내는 데 이에 따라 CPU는 어떤 인터럽트 서비스 루틴을 호출할 지 식별해야 합니다.  이를 가능하게 하는 주요 메커니즘 중 하나가 "인터럽트 벡터 테이블(IVT)"입니다.

 

IVT는 메모리 주소의 배열 또는 테이블로 생각할 수 있으며, 각 주소는 특정 인터럽트 소스에 매핑됩니다. 특정 인터럽트가 발생하면 시스템은 IVT를 참조하여 해당 ISR의 메모리 위치를 식별하게 됩니다. 이 과정은 다음과 같이 진행됩니다: 처음에는 CPU가 외부 또는 내부 인터럽트 소스로부터의 신호를 인식하게 되며, 이후 인터럽트의 종류 또는 번호에 따라 IVT에서 해당 ISR의 시작 주소를 찾습니다. 이 주소로 점프하여 ISR의 실행이 시작되며, ISR의 작업이 끝나면, CPU는 인터럽트가 발생하기 전의 상태로 복귀하게 됩니다.

 

IVT의 구체적인 위치나 구조는 시스템의 아키텍처나 특정 설계에 따라 다를 수 있습니다. 어떤 시스템에서는 IVT가 고정된 메모리 위치에 있을 수 있으나, 다른 시스템에서는 그 위치가 변경될 수 있습니다. 더욱이, IVT의 크기는 주로 시스템이 지원하는 인터럽트 소스의 개수에 따라 결정되며, 고급 시스템에서는 다양한 인터럽트의 우선순위를 관리하기 위한 추가적인 로직이나 테이블이 포함될 수 있습니다. 아래는 이러한 IVT의 한 예를 보여줍니다.

6. 인터럽트 시 Context Switch

인터럽트 처리 도중에 가장 중요한 단계 중 하나는 컨텍스트 스위치(Context Switch)입니다. 컨텍스트 스위치는 현재 실행 중인 프로세스(또는 스레드)의 상태를 저장하고, 인터럽트 처리나 다른 프로세스의 실행을 위해 해당 상태를 복원하는 과정을 말합니다. 인터럽트가 발생하면, 현재 실행 중인 작업을 나중에 다시 실행할 수 있도록 그 상태를 저장해야 합니다. 이때 저장되는 정보의 집합을 '컨텍스트'라고 합니다.

컨텍스트에 포함되는 정보는 다음과 같습니다.

  • 레지스터 값: CPU의 레지스터에 저장된 데이터는 현재 수행 중인 작업의 중요한 정보를 담고 있습니다. 일반 레지스터, 누산기, 인덱스 레지스터, 스택 포인터 등 모든 CPU 레지스터의 현재 값이 컨텍스트에 포함됩니다.
  • 프로그램 카운터: 프로그램 카운터는 다음에 실행될 명령어의 주소를 가리킵니다. 인터럽트 발생 후 원래의 작업을 계속하기 위해서는 이 주소를 알아야 합니다.
  • 프로세스 상태: 프로세스의 현재 상태(실행 중, 준비 상태, 대기 상태 등)를 나타내는 정보입니다.
  • 메모리 관리 정보: 페이지 테이블, 메모리 경계, 세그먼트 테이블 등의 메모리 관리 정보.
  • CPU 상태와 플래그: 현재 CPU의 상태 정보와 조건 플래그 등이 저장됩니다.
  • I/O 상태 정보: I/O 작업 중 발생한 인터럽트의 경우, I/O 상태와 관련된 정보(예: I/O 버퍼 상태, I/O 장치의 상태 등)도 저장될 수 있습니다.

컨텍스트 스위치가 발생하면 위와 같은 정보들이 시스템의 스택이나 특정 메모리 영역에 저장됩니다. 인터럽트 처리나 다른 프로세스의 실행이 끝난 후, 이전 프로세스를 계속 실행하기 위해 해당 메모리 영역에서 컨텍스트 정보를 가져와 CPU와 관련 시스템 상태를 복원합니다.