[OS] Interrupt

Pakxe·2023년 10월 10일
0
post-thumbnail

Interrupt

interrupt는 방해하다라는 의미인데, OS에서는 CPU가 방해받은 경우를 말한다. 뭔가 실행하는 중에 자극이 들어오면 실행중이던 작업을 멈추고 그 자극을 처리하고 멈췄던 작업으로 돌아가 이어서 일을 하게된다.

interrupt number

각 인터럽들을 식별하고 그에 맞는 처리 루틴을 실행해 적절한 대응을 해주기 위해 인터럽들에는 번호가 붙어있다. 이를 interrupt number라고 한다.

실제로 아래 HW 인터럽들(키를 누른다던지..)에 해당하는 인터럽 넘버는 사진 속 번호이다.

ISR(interrupt service routine)

각 인터럽들은 ISR(interrupt service routine)이라는 코드로 처리된다. 이 ISR은 보통 두 단계로 이루어져 있어 각각을 ISR1, ISR2라고 부른다.

운영체제의 대부분의 코드는 인터럽을 처리하는 로직이므로, 운영체제는 ISR의 집합이라고도 할 수 있다.

(initialization code = 부팅시 하는 초기화 작업들)

Interrupt의 종류

인터럽은 크게 HW interruptSW interrupt로 나뉜다.(예외 사항도 있긴함)

HW interrupt은 앞서 첨부한 이미지처럼, 외부 장치의 조작으로 인해 회로에 전기 자극이 들어와 방해받은 것을 말한다.

SW interrupt는 대표적으로 프로그램이 시스템 함수를 호출하는 경우를 말한다.

CPU는 평소에 어디?

인터럽이 발생하면 CPU는 그 방해를 적절하게 조치하기 위해 이동한다.

그러면 평소에 CPU는 어디에 있을까? 보통은 cpu_idle안에서 무한 루프를 돌고 있다.

부팅시 start_kernel함수가 실행된다고 했는데, 이 함수의 마지막 함수는 rest_init이다. 그리고 이 rest_init의 마지막 함수는 cpu_idle(arch/x86/kernel/process_32.c)인데 이 함수 내부에는 while(1)가 있어, 진입하면 무한 루프를 돌게된다.

따라서 cpu는 컴퓨터가 켜져있는 동안 이 cpu_idle함수의 무한 루프를 벗어나지 못해 평소 이곳에 계속 존재하고 있다.

그와중에 인터럽(external event)이 발생하거나 다른 프로세스를 실행해야한다면, 이동했다가 다시 cpu_idle로 돌아온다(마치 감옥처럼..) cpu가 cpu_idle을 탈출하는 방법은 컴퓨터를 종료하는 방법 뿐이지만, 어차피 컴퓨터를 부팅하면 다시 이곳으로 돌아오기 때문에 cpu가 이 cpu_idle을 아예 벗어날 방법은 없다.

system call

앞에서 시스템 함수가 SW interrupt라고 했다. 사실 시스템 함수를 보통 시스템 콜이라고 부르는데, 시스템 콜을 호출하면 이를 인터럽으로 인식해 처리하게 된다.

시스템 콜의 interrupt #은 128번으로 모두 동일하지만, 시스템 콜마다 번호가 붙어있어 이 번호로 식별하게 된다(번호의 번호.. 서브번호). 5번은 open, 3번은 read 이런 식으로 붙어있다.

isr1, isr2

isr1: 준비 단계
isr2: 실제 처리 루틴

시스템 콜 인터럽이 발생하면 INT (interrupt number)로 표현한다. 그리고 isr1 테이블로 이동해 인터럽트 처리를 위한 사전 작업 후, 실제 처리 루틴 isr2를 호출한다.

리눅스는 isr1, isr2의 위치가 다 정의되어있다.

인터럽이 발생해 처음 준비를 시작하는 위치는 모두 entey_32.S로 모두 똑같다.
isr2은 인터럽마다 위치가 다르기 때문에 하나하나 찾아봐야 알 수 있다.

IDT(interrupt descriptor table)

IDT는 isr1의 위치를 저장해준다.
이 테이블 덕분에 인터럽이 발생하면 빠르게 isr1으로 접근할 수 있는 것이다.

CPU execution cycle

CPU execution cycle에는 인터럽을 처리하는 스텝이 따로 있다.

instruction이 임의의 시스템 콜을 호출하는 함수면, INT 128 을 실행하는 식이다.

INT x


왼쪽은 일반적인 인터럽 처리 과정이고 오른쪽은 키보드 인터럽 처리 과정이다.

인터럽이 발생하면 하던 일을 멈추고, 현재 위치를 저장한다. 그래서 현재 상태를 eflag, cs, eip 레지스터에 저장하고, 인터럽을 처리하기 위해 isr1의 33번으로 이동한다(키보드 인터럽 # = 33). 여기서 초기 작업을 마친 후 isr2(33은 atkbd_interrupt)로 이동한다. 여기서 이제 본격적으로 키보드 인터럽 처리를 시작하게 되는 것이다.

사용자가 친 키를 기억하고 이 키를 화면에 출력하는 과정을 이 안에서 수행한다.

이렇게 인터럽 처리가 끝나고 저장해 두었던 중단 지점을 reschedule해, 원래 있던 곳인 cpu_idle로 돌아가게 된다.

참고

https://m.blog.naver.com/jjong_w/60107388196

0개의 댓글

관련 채용 정보