> For the complete documentation index, see [llms.txt](https://kukingclass.gitbook.io/computerscience/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kukingclass.gitbook.io/computerscience/operating-system/undefined-2.md).

# 인터럽트(Interrupt)

## 목차

* [Interrupt](#interrupt)
  * [overview](#overview)
  * [what is interrupt ⭐️](#what-is-interrupt--)
  * [인터럽트 종류](#인터럽트-종류)
  * [인터럽트 동작 순서 ⭐️](#인터럽트-동작-순서--)
  * [인터럽트 우선순위](#인터럽트-우선순위)
  * [인터럽트 구성요소](#인터럽트-구성요소)
  * [summary](#summary)

## overview

* OS에서의 **interrupt**는 ‘방해’보다는 `우선순위가 더 높은 작업을 우선적으로 처리한다`라는 의미가 더 강함.
* 일반적으로 마우스, 키보드 등 입출력 장치의 **user interaction** 작업이 더 높은 우선순위를 가짐.

ex. 키보드를 누르는 I/O 작업을 생각해보자.

[키보드를 누르면 어떤 일이 발생할까?](https://velog.io/@litien/%ED%82%A4%EB%B3%B4%EB%93%9C%EB%A5%BC-%EB%88%84%EB%A5%B4%EB%A9%B4-%EC%96%B4%EB%96%A4-%EC%9D%BC%EC%9D%B4-%EB%B0%9C%EC%83%9D%ED%95%A0%EA%B9%8C)

1. I/O 작업을 시작하기 위한 **적절한 register를 로드.**
2. device controller는 레지스터의 내용을 검사하여 **수행할 작업을 결정**. → 키보드에서 문자 읽기
3. 키보드 → 로컬 버퍼로 **데이터 전송을 시작(key code 보냄).**
4. CPU가 값을 읽어옴으로써 어떤 키가 눌러졌는지 알 수 있는 것!
5. CPU는 값을 읽어 온 뒤 ‘(화면에) 쓰기 완료'와 같은 상태 반환.

* *But, controller는 어떻게 CPU에게 작업이 완료 되었음을 알릴 수 있을까?*

  → `interrupt`를 통해 수행!

  → CPU에게 키보드를 치고 있으니 처리해주라는 interrupt를 걸어주는 것!

***

## what is interrupt ⭐️

* interrupt란?

```
CPU가 프로그램을 실행하고 있을 때, 
예외 상황이 발생할 경우 현재 실행 중인 작업을 즉시 중단하고, 
CPU에 알려서 예외를 우선 처리하는 기술.

-> 쉽게 말해 CPU와 다른 장치들이 커뮤니케이션 할 수 있게 하는 것!
```

* 주변 장치와 입출력 장치는 CPU와 메모리와 달리 interrupt 라는 매커니즘으로 관리

> **그래서 인터럽트를 왜 하는데?**

→ 입출력 연산이 CPU 명령 수행 속도보다 현저히 느리기 때문!

* 아주 오래걸리는 입출력 연산을 CPU가 매번 기다릴 수는 없음
  * 인터럽트는 입출력 연산이 완료되면 → 그때 CPU에게 작업 완료를 알려줌
  * CPU가 다시 중단 되었던 작업을 이어서 할 수 있도록 함

***

## 인터럽트 종류

* 외부/내부 인터럽트 - `CPU의 하드웨어 신호에 의해 발생`
* 소프트웨어 인터럽트 - `명렁어의 수행에 의해 발생`

1. **외부 인터럽트 (하드웨어 인터럽트)**
   * 주로 하드웨어 등 프로그램 외부에서 발생하는 인터럽트
   * CPU가 아닌 다른 하드웨어 장치가 CPU에 어떤 사실을 알려주거나 CPU 서비스를 요청해야 할 경우 발생

* **Interrupt mask**(인터럽트가 발생하였을 때 요구를 받아들일지 말지 지정하는 것) 여부에 따라
  * `Maskable interrupt`
    * Interrupt Mask 가능
    * 인텔CPU 에서 **INTR pin**으로 신호가 들어옴
  * `Non Maskable interrupt`
    * Interrupt mask 불가능
    * 거부 or 무시 불가능⭐️
    * 정전, 하드웨어 고장 등 어쩔 수 없는 오류
    * 인텔CPU 에서 **NMI pin**으로 신호가 들어옴
* 발생 원인에 따라
  * `입출력 인터럽트 (I/O interrupt)` - 입출력 작업의 종료나 입출력 오류에 의해 CPU의 기능이 요청됨
  * `전원 이상 인터럽트 (Power fail interrupt)` - 전원 공급의 이상
  * `기계 착오 인터럽트 (Machine check interrupt)` - CPU의 기능적인 오류
  * `외부 신호 인터럽트 (External interrupt)` - I/O 장치가 아닌 오퍼레이터나 타이머에 의해 의도적으로 프로그램이 중단된 경우

2. **내부 인터럽트**
   * 주로 프로그램 내부에서 잘못된 명령어나 데이터 사용시 발생하는 인터럽트 (소프트웨어 실행중에)
   * **시스템 콜**에 의해 발생
   * `Trap`이라고 부름
   * 프로그램 검사 인터럽트(Program check interrupt)
     * Division by zero
     * Overflow / Underflow
     * 기타 Exception
3. **소프트웨어 인터럽트**
   * 프로그램 처리 중 명령어 요청에 의해서 발생 (런타임 실행중에)
   * `SVC`(SuperVisor Call)
     * 사용자가 프로그램을 실행시키거나 감시프로그램(Supervisor)을 호출하는 동작을 수행하는 경우
     * 복잡한 입출력 처리를 하는 경우

***

#### +인터럽트 종류 추가

하드웨어/내부/소프트웨어 인터럽트 대신, 인터럽트 / 트랩 / SVC로 나누어 보는 경우도 있어서 추가합니다! (인터럽트와 트랩의 차이를 설명하라는 면접 질문 존재)

|          | 원인                  | 설명              |
| -------- | ------------------- | --------------- |
| 인터럽트     | 현재 명령어 수행의 외부(I/O)  | 비동기적인 예외 상황에 호출 |
| 트랩       | 현재 명령어 수행과 관련(예외처리) | 오류나 예외 상황 처리    |
| 수퍼바이저 호출 | 명시적 호출              | 운영체제 기능에 대한 호출  |

### 인터럽트

```
- 현재 수행 중인 프로세스와 독립적으로 외부에서 유발되는 여러 종류의 사건에 의해 발생(io)
- 종류
    - timer 인터럽트
        - time slice를 다 사용해서. 시간초과
    - I/O 인터럽트
        - 발생된 입출력 행위가 하나 이상의 프로세스가 대기하던 친구라면 대기하던 친구들때문에 블록되어있던 모든 프로세스를 준비상태로 바꾸고,
        현재 수행하고 있는 프로세스를 계속 진행할지 우선순위로 인해 다른 애로 갈아탈지 결정
    - memory fault(메모리 부재)
        - 메모리에 프로세스가 접근했는데 프로세스 정보가 보조기억장치에 스왑된 경우 다시 올려줘야함.
        - 메모리 블록을 가져오기 위한 입출력 요청 후 메모리 폴트 유발시킨 프로세서 block시킴
        - 또 사른 프로세스를 수행시키기 위해 프로세스 교환 수행
        - 원하던 블록이 메모리로 적재되면 메모리 폴트를 유발시킨 프로세스 준비상태로
```

### 트랩

```
- 불법적인 파일 접근 시도처럼 현재 수행되고 있는 프로세스에서 생성되는 오류나 예외 조건때문에 발생
- 관련 오류나 예외 상황이 치명적인지 판단
    - 치명적
        - 현재 수행되고 있는 프로세스 종료 상태로 전이
    - 안 치명적
        - 복구 프로시저 실행하거나 사용자에게 통보
```

### 수퍼바이저 호출

```
- ex) 사용자 프로세스가 수행 중에 파일 개방과 같은 입출력 동작을 요구하는 명령을 수행하면,
일련의 방식으로 제어를 넘기게 되고, 이 호출로 인해 해당 사용자 프로세스는 블록 상태로 전이
```

***

## 인터럽트 동작 순서 ⭐️

* 요청 - 중단 - 보관 - 처리 - 재개

1. **인터럽트 요청 신호 발생**
2. **프로그램 실행 중단**
   * 현재 실행중이던 `Micro Operation` 까지 수행
3. **현재 프로그램 상태 보관 (복귀 주소를 stack에 저장, context switching)**
   * 현재 수행중이던 상태를 PCB에 저장 (메모리 주소, 레지스터 값, 하드웨어 상태 등)
   * `Interrupt Vector`를 읽어 ISR 주소 값을 얻음
   * PC에 다음 실행할 명령의 주소 저장, ISR로 jump
4. **인터럽트 서비스 루틴 실행**
   * 인터럽트 원인 파악 후 실질적인 작업 수행
   * 서비스 루틴 수행 중, 우선 순위가 더 높은 인터럽트 발생 → 다시 1번부터 수행
5. **보관한 복귀 주소 값을 복원하여 중단된 프로그램 재실행**
   * 레지스터 복원
   * ISR 끝에 `RETI` 명령어에 의해 인터럽트 해제

![Untitled 1](https://user-images.githubusercontent.com/85485290/189528340-563ed1b7-bc2a-4921-990e-3db0c4c19425.png)

***

## 인터럽트 우선순위

* 일반적으로 하드웨어 인터럽트가 소프트웨어 인터럽트보다 우선 순위가 높고,
* 외부 인터럽트가 내부 인터럽트보다 우선 순위가 높다.

![](https://user-images.githubusercontent.com/85485290/189528422-b719f212-497d-4abe-ab3c-4ff941628f71.png)

* 우선 순위 판별 방법
  * 소프트웨어적 방법 (Polling)
  * 하드웨어적 방법 (Vectored Interrupt)

***

## 인터럽트 구성요소

1. **발생원(Source)** : 누가 인터럽트를 요청했는지
2. **우선순위(Priority)** : 2개 이상의 요청시 어떤 서비스를 먼저 할 것인지 ?
3. **인터럽트 벡터(Interrupt Vector)** : 서비스 루틴(ISR)의 시작 번지는 어디인지

* • `인터럽트 벡터 테이블` : 주기억장치의 특정 영역에 여러 개의 인터럽트에 대한 인터럽트 벡터를 모아놓은 영역

***

## summary

* 운영체제는 평소에는 대기 상태이다가 하드웨어 인터럽트 / 소프트웨어 인터럽트 / 내부 인터럽트에 의해 운영체제 내부의 코드(**ISR**)이 실행됨.
* interrupt를 발생 시켜 CPU가 중단되면 → CPU가 하던 작업을 중지하고 즉시 고정된 위치로 실행을 전송

  → 고정 위치에는 인터럽트의 서비스 루틴이 위치한 시작 주소가 포함됨.

  → 이 때 중단된 시점의 정보를 알고 있는 것 == **PCB**
* 인터럽트는 고유 번호를 가짐
  * 해당 번호가 가진 코드가 존재 = 운영체제 안에 정해져있음 (ISR)
  * 코드 번호와 코드에 대한 정보는 IDT(Interrupt Descriptor Table)에 존재
  * 인터럽트가 발생하면 IDT를 참조해서 ISR을 실행!
* interrupt는 **운영체제와 하드웨어가 상호작용**하는 방식의 핵심 부분!
