운영체제가 어떻게 하드웨어 위에서 돌아갈까?
중앙처리 장치, 하드웨어
매 순간 메모리에서 instruction(기계어)을 하나씩 읽어서 실행한다
1) register : 메모리보다 빠르면서 저장할 수 있는 공간들
2) mode bit : CPU에서 실행되는 것이 운영체제인지 사용자 프로그램인지 구분해주는 것
3) interrupt line :
CPU는 메모리랑만 일을 한다. 메모리에 있는 instruction을 실행한 뒤 주소값을 증가해 다음 instruction을 실행한다. 그러므로 I/O 기기에서 데이터를 읽어올 때는 CPU가 직접 접근하는 게 아니라 device controller에게 일을 시키고, controller가 정해진 작업을 끝내면 I/O device의 local buffer에 결과를 저장해두고 interrupt line이 CPU에게 알려준다. 그 동안 CPU는 다른 메모리 접근을 하면서 instruction을 실행한다.
ex. 프로그램 A가 CPU를 가지고 있으면, CPU가 A의 instruction만 읽다가 disk에서 데이터를 읽어와야 할 때 I/O device니까 device controller가 읽어오는 동안 CPU는 다른 프로그램을 돌리다가 local buffer에 저장을 하고 끝나면 interrupt line을 통해 정보를 받아서 다음 작업을 한다
=> 이렇게 CPU는 빠르게 여러 프로그램을 돌아가면서 실행하므로 동시에 실행하는 것처럼 보인다
-CPU의 작업 공간
input - 입력을 받아서 컴퓨터가 받는 것 ex. 키보드, 마우스
output - 입력에 대해 처리를 해서 돌려주는 출력 ex. 모니터, 프린터
ex. 하드디스크 : 내용을 읽기도 하고 (입력), 컴퓨터에서 처리된 데이터를 저장하기도 한다(출력)
=> 컴퓨터가 아닌 별개의 기기들이다
1) device controller들이 붙는다
2) local buffer가 붙는다
I/O관련 instruction을 읽을 때 프로그램은 직접 기기에 접근할 수 없으므로 운영체제에게 I/O를 해달라고 CPU를 넘겨준다. 그러면 운영체제가 이 작업을 device controller에게 넘긴다. 그리고 해당 작업이 끝나서 local buffer이 들어오면 device controller가 CPU에게 interrupt를 건다. 그러면 다른 프로그램에 있었던 CPU가 운영체제에게 가고 운영체제에서 interrupt를 확인한 뒤 local buffer의 내용을 해당 프로세스의 메모리 영역으로 카피를 해주고 방금까지 CPU를 쓰던 프로그램에게 다시 CPU를 주고 정해진 시간이 다 될 때까지 쓸 수 있도록 한다.
ex. 문제 : 무한루프를 도는 프로그램(while 등)을 만나면 어떻게 될까?
-> CPU가 다른 프로그램에게 넘어가지 않아서 time sharing이 일어나지 않는다
-> 이를 해결하기 위해 timer가 있다
한 프로그램의 CPU 독점을 막기 위해 사용하는 방법
운영체제가 처음에 컴퓨터를 켰을 때 CPU를 프로그램에 넘겨주기 전에 timer에 특정 값을 세팅해서 넘겨준다. 그러면 프로그램이 독점을 할 수 없고 timer에 할당된 시간 수십ms정도씩 프로그램을 돌아가면서 instruction을 실행한다.
그러다가 정해진 시간이 되면 timer가 CPU에게 interrupt를 건다. 그러면 CPU는 매번 instruction을 하나씩 실행하다가 하나가 끝나면 interrupt line을 체크한다 (하나씩 돌아가면서)
만약 타이머가 interrupt를 걸었으면(timer interrupt) CPU는 하던일을 멈추고 제어권을 사용자 프로그램에서 운영체제로 자동으로 넘어간다
CPU : 운영체제 -> timer 세팅 후 사용자 프로그램A -> timer 시간이 끝나면-> 운영체제 -> 사용자 프로그램B -> ... -> 프로그램A 종료 -> 운영체제
운영체제가 프로그램에 한번 넘어가면 임의로 뺏지 못하고 이런 경우에만 돌려준다. 또 프로그램 실행이 종료되면 자동 반납을 한다
-> 제한된 instruction만 CPU에서 실행 가능.
보안상의 목적으로 I/O 접근은 못함.
(I/O device 접근X, 다른 프로그램 메모리 공간 접근x, 운영체제 메모리 위치 접근X)
interrupt나 exception 발생 시 하드웨어가 mode bit을 0으로 바꿈
운영체제가 CPU를 넘겨줄 때 시간을 설정해준 다음 전달
정해진 시간이 흐른 뒤 운영체제에게 제어권이 넘어가도록 인터럽트 발생시킴
타이머는 매 클럭 틱 때마다 1씩 감소
타이머 값이 0이 되면 타이머 인터럽트 발생
CPU를 특정 프로그램이 독점하는 것으로부터
I/O device controller
해당 I/O 장치 유형을 관리하는 일종의 작은 CPU
- 제어 정보를 위해 control register, status register를 가짐
CPU가 지시할 때 사용하는 것들
명령은 제어 레지스터를 통해 CPU에 전달
- local buffer를 가짐(일종의 data register)
data를 담는 거는 메모리가 아닌 여기에 저장
CPU가 여기서 데이터를 복사해서 프로세스의 주소 공간에 저장한다
device는 CPU의 메모리에 접근 불가
- I/O는 실제 device와 local buffer 사이에서 일어남
Device controller는 I/O가 끝났을 경우 interrupt로 CPU에 그 사실을 알림
cf. memory controller라는 것도 있다
direct memory access controller
직접 메모리에 접근할 수 있는 컨트롤러
원래는 CPU만 접근 가능하지만 이를 이용하면 DMA도 접근 가능
만약 CPU와 DMA가 동시에 메모리에 접근하면 에러가 생길 수 있으므로 memory controller가 중재를 해준다
I/O가 너무 자주 CPU를 interrupt
그러므로 DMA가 들어오는 I/O의 interrupt마다 local buffer에 있는 데이터를 복사해서 한번에 CPU에게 전달
모든 입출력 명령은 특권 명령
사용자 프로그램은 어떻게 I/O를 하는가?
stystem call이란?
사용자 프로그램이 운영체제의 서비스를 받기 위해 커널 함수를 호출하는 것
I/O는 보안 상의 목적 때문에 직접 device에 접근하기 어려우므로
사용자 프로그램을 실행하다 함수 호출을 하는 부분이 있으면 함수 내 다른 함수를 호출하면 instruction을 순차적으로 실행하다가 메모리 위치를 점프한다. 이건 내부적으로 가능한데, 만약 I/O 함수를 호출하면 사용자 프로그램 자체적으로 할 수 없다. 모드 빗도 1로 되어 있으므로 운영체제에 접근하기 위해 프로그램이 직접 interrupt line을 세팅하는 instruction을 실행한다. 이때 프로그램이 운영체제에게 요청하기 위한 interrupt를 했기 때문에 모드빗이 0이 되고 CPU가 운영체제로 넘어가서 기기에게 작업을 요청할 수 있다.
: 입터럽트 당한 시점의 레지스터와 program counter를 save한 후,
CPU의 제어를 인터럽트 처리 루틴에 넘긴다
sw interrupt (= trap) :
system call : 프로그램이 커널 함수를 호출하는 경우.
사용자 프로그램이 직접 인터럽트를 걸어서 운영체제에게 CPU를 넘기는 방식.
그러므로 OS는 항상 올바른 요청인지 확인을 하고 I/O controller에게 요청을 한다
exception : 프로그램이 오류를 범한 경우
hw interrupt : 하드웨어가 발생시킨 인터럽트 ex. timer, I/O controller
보통 인터럽트는 hw interrupt를 의미한다 (좁은 의미)
관련 용어
인터럽트 벡터
- 해당 인터럽트의 처리 루틴 주소를 가지고 있음
인터럽트 종류마다 어디에 있는 함수를 실행해야 하는지 위치를 정리해놓은 테이블
인터럽트 처리 루틴
(= interrupt service routine, 인터럽트 핸들러)
I/O를 하기 위해 두가지 interrupt
사용자 프로그램 -> I/O요청 시 system call(sw interrupt) -> OS -> controller -> device -> I/O 요청이 끝나면 hardware interrupt
현대의 운영체제는 인터럽트에 의해 구동된다!