07. 인터럽트
인터럽트란?
CPU가 프로그램을 실행하고 있을 때,
입출력 하드웨어 등의 장치나 또는 예외 상황이 발생하여 처리가 필요할 경우
CPU에 알려서 처리하는 기술
어느 한 순간 CPU가 실행하는 명령은 하나! 다른 장치와 커뮤니케이션 어떻게?
컴퓨터 구조단 생각해보기
PC(program counter)는 (instruction) code 한줄 한줄을 실행하는데 집중
외부 이벤트 처리해야할 때, 정보를 어떻게 처리할까
처리가 끝났다는 것을 OS에 알려주기.
OS 코드 레벨로 생각해보기
저장 매체에서 파일을 읽어 들일 때, blocking상태(event)에 빠진 상태를
어떻게 CPU에 끝났다고 알려서 ready 상태 로 변경?
(이 기술을 interrupt라고 한다)
즉, event 발생 => (인터럽트) => 처리(kernel code)
(현재 사용 중인 사용자 프로그램을 잠시 멈추고, CPU의 제어권을 운영체제로 양도한다)
예외 상황 핸들링
CPU가 프로그램을 실행하고 있을 떄, 입출력 하드웨어 등의 장치 또는 예외 상황 발생한 경우 CPU가 해당 처리를 할 수 있도록 CPU에 알려 줘야 함.
0으로 나누는 연산과 같은 예외 발생 상황도, CPU는 처리를 하려고 한다.
그래서 문제가 생길 수 있다. 이런 예외 상황을 운영체제, 스케쥴러에 알려서
프로세스를 kill(error 메세지 발생) 해야 한다. 이 때 정보를 알려 주는 것을 인터럽트라고 할 수있다.
선점형 스케쥴러에서 사용되는 방법
이벤트를 정의하고, 발생했을 때 처리하는 것을 인터럽트라고 한다.
인터럽트는, 일종의 이벤트로 불린다.
이벤트에 맞게 운영체제가 처리하도록 구현되어있다.
인터럽트 종류
내부 인터럽트(trap, sw인터럽트)
주요 프로그램 내부에서 잘못된 명령(예외 상황) 또는 잘못된 데이터 사용 시 발생
주로 프로그램 내부에서 발생하므로, 소프트웨어 인터럽트라고도 함
Divide-by-Zero Interrupt: 0으로 나누는 코드 실행 시
사용자 모드(user mode)에서 허용되지 않는 명령 또는 공간 접근 시
C언어에서 pointer가 가리키는 주소가 잘못됬을 때
Linux에서 0-4GB를 '프로세스'공간이라고 함. 이 때,
0-3GB는 user mode
3-4GB를 kernel mode라고 함.
사용자 모드에서 process로 실행하다가, 포인터가 kernel모드를 가리켰을 때 에러 발생
계산 결과가 Overflow/Underflow 날 때
int 변수 type 지정시, 32bit
unsigned(부호 없는 것)
signed(부호 있는 것) (2³¹만큼 수 표현)
이 때 1 bit는 부호를 표시함.
2³¹ + 2³¹ => overflow
(컴구에서 overflow본것 다시 정리)
음수로 표현 가능한 범위를 벗어난 경우 =>underflow
외부 인터럽트(hw인터럽트):
주로 하드웨어에서 발생되는 이벤트(프로그램 외부)
주로 하드웨어에서 발생하므로, 하드웨어 인터럽트라고도 함.
전원 이상
기계 문제
I/O 관련 이벤트: 프린터, 마우스, 키보드, 저장 매체(SSD등)
timer interrupt: 선점형 스케쥴러 위해 필요
H/W로 부터 일정시간마다 타이머 인터럽트를 OS(kernel모드)에 알려줌
일정 시간마다, process를 교체하겠다.
인터럽트 내부 동작
시스템콜 인터럽트
시스템콜 실행을 위해서는 강제로 코드에 인터럽트 명령을 넣어, CPU에게 실행 시켜야 한다.
시스템 콜 실제 코드(어셈블리어_인텔기준)
eax 레지스터에 시스템 콜 번호를 넣고,
ebx 레지스터에 시스템 콜에 해당하는 인자 값을 넣고,
소프트웨어 인터럽트 명령을 호출하면서 0 X 80 값을 넘겨줌.
여기서 쓰인 int = interrupt
시스템 콜 인터럽트 명령을 호출하면서, 0X80 값을 넘겨줌
CPU는 사용자 모드를 커널 모드로 바꿔줌
IDT(Interrupt Descriptor Table)에서 0 X 80에 해당하는 주소(함수) 찾아 실행
[interrupt 번호 : 주소(함수 코드)]
system_call()함수에서 eax로부터 시스템 콜 번호를 찾아서, 해당 번호에 맞는 시스템콜 함수로 이동
[시스템콜번호: kernel function(system call)]
해당 시스템콜 함수 실행 후, 다시 커널 모드에서 사용자 모드로 변경하고, 다시 해당 프로세스 다음 코드 실행
인터럽트와 IDT
인터럽트는 미리 정의되어 각각 번호와 실행 코드를 가리키는 주소가 기록되어있다.
어디에? IDT(Interrupt Descriptor Table)에 기록
언제? 컴퓨터 부팅 시 운영체제가 (테이블을) 기록
어떤 코드? 운영체제 내부 코드
정리
항상 인터럽트가 발생하면, IDT(Interrupt Descriptor Table)을 확인한다.
시스템콜 인터럽트 명령은 0X80 번호가 미리 정의.
인터럽트 0X80 에 해당하는 운영체제 코드는 system_call()이라는 함수
즉 IDT에는 0X80 => system_call()과 같은 정보가 기록되어있음.
리눅스 예
0~31: 예외상황 인터럽트(내부/소프트웨어 인터럽트)
일부는 정의 안된 채로 남겨져 있음
32~47: 하드웨어 인터럽트(주변장치 종류/갯수따라 변경가능)
128: 10진수로 0X80을 표현
인터럽트와 프로세스 정리
프로세스 실행 중, 인터럽트 발생
현 프로세스 실행 중단
인터럽트 처리 함수 실행(운영체제, 커널 모드)
현 프로세스 재 실행
선점형 스케쥴러 예시
수시로 timer interrupt가 발생
OS 가 timer interrupt횟수를 기억했다가 예를 들어 5번 이상 발생한다면 현재 프로세스 중지하고, 다른 프로세스 실행한다.
Last updated