주변장치와 입출력 장치는 CPU나 메모리와 달리 인터럽트라는 매커니즘을 통해 관리된다.
그러면 인터럽트는 왜 필요할까? 왜냐하면, 입출력 연산이 CPU 명령 수행속도보다 현저히 느리기 때문이다. 즉, OS를 사장, CPU를 고급 인력이라고 하자. 그런데 OS 입장에서 CPU가 입출력 처리를 하면 고급 인력을 낭비하는 셈이어서, 입출력 직원에게 자신의 업무가 완료되면 그때 CPU에게 작업 완료를 알리라고 지시하고, 입출력 직원의 입무가 완료되면 그때 CPU에게 작업 완료를 알린다. 여기서 입출력 직원이 CPU에게 작업 완료를 알려주는 것이 인터럽트이다.
그럼 이제 인터럽트에 대해 컴퓨터 구조 관점에서 더 자세히 알아보자.
인터럽트 정의
CPU가 프로그램을 실행하고 있을때, 입출력 하드웨어 등의 장치나 예외상황이 발생하여 처리가 필요한 경우에 마이크로 프로세서에게 알려 처리할 수 있도록 하는 것을 말한다. 이런 인터럽트는 크게 하드웨어 인터럽트와 소프트웨어 인터럽트로 나뉜다.
하드웨어 인터럽트
하드웨어가 발생시키는 인터럽트로 CPU가 아닌 다른 하드웨어 장치가 CPU에 어떤 사실을 알려주거나 CPU 서비스를 요청해야할 경우에 발생시킨다.
소프트웨어 인터럽트
소프트웨어가 발생시키는 인터럽트이다. 이때, 소프트웨어(사용자 프로그램)이 스스로 인터럽트 라인을 세팅한다. 종류에는 예외 상황, system call 등이 있다.
인터럽트를 발생시키기 위해 하드웨어/소프트웨어는 CPU 내에 있는 인터럽트 라인을 세팅하여 인터럽트를 발생시킨다. CPU는 매번 명령을 수행하기 전에 인터럽트 라인이 세팅되어 있는지를 검사한다.
그럼 이제 인터럽트 과정에 대해서 자세히 알아보기 위해 process A 실행중에 디스크에서 어떤 데이터를 읽어오라는 명령을 받았다고 가정해보자.
인터럽트 과정
- process A는 system call을 통해 interrupt를 발생시킨다.
- CPU는 현재 진행중인 기계어 코드를 완료한다.
- 현재까지 수행중이었던 상태(수행중이던 메모리 주소, 레지스터 값, 하드웨어 상태 등)을 해당 프로세스의 PCB(process control block)에 저장한다.
- PC에 다음에 실행할 명령의 주소를 저장한다.
- 인터럽트 벡터를 읽고, ISR 주소값을 얻어 ISR(Interrupt Service Routine)으로 점프하여 루틴을 실행한다.
- 해당 코드를 실행한다.
- 해당 일이 다 처리하면 대피시킨 레지스터를 복원한다.
- ISR의 끝에 IRET 명령어에 의해 interrupt가 해제된다.
- IRET 명령어가 실행되면, 대피시킨 PC 값을 복원해서 이전 실행 위치로 복원한다.
여기서 인터럽트 벡터란 인터럽트 발생시 처리해야 할 인터럽트 핸들러의 주소를 인터럽트 별로 보관하고 있는 테이블이다. 또한 인터럽트 핸들러란 실제 인터럽트를 처리하기 위한 루틴으로 인터럽트 서비스 루틴이라고도 한다. 운영체제의 코드 영역에는 인터럽트별로 처리해야할 내용이 이미 프로그램되어 있다. 또한 PCB란 커널의 데이터 영역에 존재하며, 각각의 프로세스마다 고유의 PCB가 존재한다. 따라서 interrupt 발생시, 프로세스의 어느 부분이 수행되었는지를 저장한다.
인터럽트와 특권 명령
CPU가 수행하는 명령에는 일반 명령과 특권 명령이 있다. 일반 명령은 메모리에서 자료를 읽어오고, CPU에서 계산을 하는 등의 명령이고, 모든 프로그램이 수행할 수 있는 명령이다. 특권 명령은 보안이 필요한 명령으로 입출력 장치, 타이머 등의 장치를 접근하는 명령이다. 특권 명령은 항상 운영체제만이 수행할 수 있다.
또한 OS는 하드웨어적인 보안을 유지하기 위해 기본적으로 2가지 operation을 지원한다. kernel mode는 운영체제가 CPU의 제어권을 가지고 명령을 수행하는 모드로 일반 명령과 특권 명령 모두 수행할 수 있다. 반면에 user mode는 일반 사용자 프로그램이 CPU 제어권을 가지고 명령을 수행하는 모드이기 때문에 일반 명령만을 수행할 수 있다.
시스템 콜
process A가 프로그램 명령 수행중에 디스크 입출력 명령을 읽은 경우를 생각해보자. 사용자 프로그램은 입출력 장치에 접근하는 명령을 수행할 수 없다. 왜냐하면, user mode에서는 특권 명령을 수행할 수 없기 때문이다. 이런 경우에는 사용자 프로그램은 OS에게 시스템 콜을 통해 특권 명령을 수행해달라고 요청한다. 시스템 콜은 주소 공간 자체가 다른 곳(kernel의 code 영역)으로 이동해야 하므로, 프로그램이 인터럽트 라인에 인터럽트를 세팅하는 명령을 통해 이루어진다.
즉, 시스템 콜을 정의하면, 시스템 콜은 커널 영역의 기능을 사용자 모드가 사용 가능하게. 즉, 프로세스가 하드웨어에 직접 접근해서 필요한 기능을 사용할 수 있게 해주는 것이다. 과정은 다음과 같다.
- CPU가 인터럽트 라인을 검사하고, 인터럽트가 발생한 것을 감지한다.
- 현재 수행중인 사용자 프로그램을 잠시 멈추고 CPU의 제어권을 운영체제에게 양도한다. (kernel mode)
- 그리고 이때 하드웨어적으로 모드 비트가 1에서 0으로 자동으로 세팅되어 특권 명령을 수행할 수 있게 된다.
인용
https://velog.io/@adam2/%EC%9D%B8%ED%84%B0%EB%9F%BD%ED%8A%B8
'컴퓨터 사이언스 > 운영체제' 카테고리의 다른 글
Explicit Allocator - Segregated Free List (0) | 2023.11.15 |
---|---|
Explicit Allocator - Explicit Free List (0) | 2023.11.15 |
demand-zero memory (0) | 2023.11.15 |
DMA (0) | 2023.11.14 |
동적 메모리 할당기 구현 (1) | 2023.11.13 |