프로그래밍/운영체제

공룡책으로 운영체제 공부하기[인터럽트 : Interrupt]

백사니 2025. 4. 15. 16:06
728x90
반응형

인터럽트란?

입출력 작업을 위해 장치 드라이버는 장치 컨트롤러의 레지스터에 명령어 또는 주소를 적재하여 장치에 작업을 지시한다. 컨트롤러는 이 명령에 따라 장치와 데이터를 주고받고, 완료되면 장치 드라이버에게 인터럽트를 통해 작업 완료 사실을 알린다.

예를 들어 읽기 요청의 경우, 컨트롤러는 데이터를 장치에서 로컬 버퍼로 복사하고, 완료되면 인터럽트를 발생시켜 CPU에 알린다. CPU는 이를 감지하고 **인터럽트 서비스 루틴(ISR, Interrupt Service Routine)**을 실행해 결과를 처리한다. 쓰기 요청이나 다른 I/O 작업도 마찬가지로 ISR이 결과 또는 상태 정보를 처리한다.


인터럽트의 역할

인터럽트는 단순한 입출력 통지 외에도, 사용자 입력 (키보드, 마우스), 하드웨어 이벤트 (디스크, 네트워크), 시스템 콜, 예외(Exception) 발생 같이 중요한 이벤트에 즉시 반응하기 위한 시스템 전체의 알림 시스템으로 활용된다:


인터럽트 감지 방식과 성능

CPU는 하나의 기계어 명령어가 완료될 때마다 인터럽트 요청 라인(interrupt request line)을 감지한다. 
그렇다면 매우 짧은 순간마다 이를 검사하면 성능상으로 문제가 생기지 않을까?

놀랍게도 그렇지 않다. 이유는 이 감지가 소프트웨어적인 if 문 체크가 아니라, 하드웨어 수준에서 매우 빠르게 동작하기 때문이다.
왜 명령어 단위로 감지하냐면, 명령어 실행 도중 인터럽트를 처리한다면 레지스터나 메모리 상태에 문제가 생길 수 있기 때문이다.


인터럽트 처리의 흐름

하드웨어 인터럽트 발생:
장치 컨트롤러가 시스템 버스를 통해 인터럽트 요청(IRQ)을 발생시킴.

CPU 인터럽트 감지:
CPU는 현재 명령어 실행이 끝난 뒤, 인터럽트 요청 라인을 감지함.
(이 감지는 매우 빠르게, 하드웨어 수준에서 이뤄짐)

인터럽트 벡터 테이블 조회:
인터럽트 번호(벡터)를 이용해 **인터럽트 벡터 테이블(IVT)**에서 ISR 주소를 조회함.
→ 이때 인터럽트 번호는 테이블의 인덱스 역할을 함 (lookup table 방식).

ISR 실행:
해당 인터럽트 번호에 등록된 ISR을 호출하여 이벤트 처리 수행.

원래 작업 복귀:
인터럽트 직전의 작업 상태(프로그램 카운터, 레지스터 등)를 복구하고, 다시 원래 실행하던 코드로 복귀함.

이러한 실행 순서를 통해 CPU는 마치 아무 일도 없었던 것처럼 자연스럽게 복귀하게 된다. 이 복원 덕분에 인터럽트는 매우 짧고 빠르게 처리될 수 있다.

그렇다면 인터럽트가 매우 많이 일어난다면 어떻게 될까?
앞서 봤던 것에 의하면 인터럽트는 빠르게 반응해야하는데 이런 인터럽트가 많이 일어나 빠르게 반응하지 못한다면?


인터럽트 과부하 상황 대응

인터럽트는 빠르게 처리되어야 하지만, 너무 많은 인터럽트가 한꺼번에 발생하면 처리 지연이 발생할 수 있다. 이를 방지하기 위해, 하드웨어와 운영체제는 3가지 기능을 제공한다.

1. 중요한 처리 중에 인터럽트 처리를 연기할 수 있어야한다.
2. 장치의 적절한 인터럽트 핸들러로 효율적인 디스패치를 해야한다.
3. 운영체제가 우선순위가 높은 인터럽트를 적절하게 먼저 대응해야한다.

 대부분의 CPU에는 2개의 인터럽트 요청 라인이 존재한다. 하나는 복구할 수 없는 메모리 오류 같은 이벤트를 위해 예약된 마스킹 불가능 인터럽트, 또 하나는 마스킹 가능이다. 
여기서 말하는 마스킹은 잠시 무시한다는 뜻으로 중요한 연산을 위해서 잠시 인터러브를 시키지 않는다는 이야기이다.

 마스킹 불가능 인터럽트는 CPU가 무시하면 안되는 인터럽트로 치명적인 이벤트를 처리하기 위해 존재한다.

예를 들어 메모리 오류, 하드웨어 오작동, 긴급 정전 등이 있다. 이는 시스템 안정성을 위해 즉시 처리되어야한다.


 마스킹 가능 인터럽트는 일반적인 I/O 요청 같은 경우로 중요하지만 마스킹 불가능 인터럽트보다 중요도가 떨어지는 것을들 말한다. 키보드 입력, 디스크 읽기 완료, 네트워크 패킷 도착 등 장 컨트롤러가 서비스를 요청하기 위해 사용된다.

 

 이전에 이러한 인터럽트 요청은 인터럽트 테이블로 이루어진다 했는데 마스킹 불가능 인터럽트는 0~31번 마스킹 가능 인터럽트는 32~255번에 위치해있다.

 

인터럽트 체인 구조

 이렇게 인터럽트 테이블에 각 인터럽트에 맞는 인터럽트 호출 주소가 저장이 되어있는데. 같은 인터럽트여도 다른 장치에서 인터럽트가 발생했을 경우도 있다.(키보드, 마우스 등)

이러한 상황을 전부 고려해서 전부 인터럽트 테이블에 저장한다면 테이블의 사이즈가 매우 커질것이다. 때문에 같은 인터럽트에 다른 장치들은 단일 연결리스트처럼 구현한다.

만약 36번 인터럽트가 발생했으면 36번에 첫번째 인터럽트 서비스 루틴의 주소를 호출한다. 이후 첫번째 장치가 호출의 대상인지 확인하고 아니라면 첫번째 장치에 연결된 두번째 장치에 이 호출을 넘겨준다. 이후 리스트 끝날 때까지 순회하며 담당 장치를 찾는다.

 새로운 장치가 추가되면 마지막 장치와 연결해 이어준다.

728x90
반응형