
컴퓨터는 CPU, 메모리(memory), 입출력 장치(I/O device) 세 덩어리로 나뉩니다.
여기서 중요한 전제가 하나 있습니다. 메모리는 CPU의 작업 공간이라는 것입니다. CPU는 디스크에 있는 데이터를 직접 읽지 못합니다. 반드시 메모리에 올라온 것만 처리합니다. 프로그램을 실행한다는 말은 실행 파일을 메모리에 올리고, CPU가 메모리에서 명령을 하나씩 읽어 실행한다는 뜻입니다.

나머지 부품은 전부 이 그림에서 생기는 문제를 하나씩 막기 위해 존재합니다.
mode bit이 없다고 해봅니다. 그러면 사용자 프로그램이 디스크에 직접 명령을 내려 남의 파일을 지울 수 있고, 다른 프로그램이 쓰는 메모리 영역을 마음대로 덮어쓸 수 있습니다. 프로그램 하나가 시스템 전체를 망가뜨립니다.
그래서 CPU 안에 비트 하나를 둡니다. 이것이 mode bit입니다.
모니터 모드는 커널 모드(kernel mode), 시스템 모드(system mode)라고도 부릅니다. 입출력 명령처럼 mode bit이 0일 때만 실행할 수 있는 명령을 특권 명령(privileged instruction)이라고 합니다.
전환 규칙은 단순합니다. 인터럽트나 예외가 발생하면 하드웨어가 mode bit을 0으로 바꾸고 운영체제에 CPU를 넘깁니다. 운영체제가 사용자 프로그램에 CPU를 넘길 때는 1로 바꿔 놓고 넘깁니다. mode bit을 바꾸는 것 자체가 특권 명령이므로, 사용자 프로그램이 스스로 0으로 만들 수는 없습니다.
mode bit으로 권한은 막았지만 아직 문제가 남습니다. 사용자 프로그램이 while(1); 을 실행하면 CPU를 영원히 붙잡고 놓지 않습니다. 운영체제도 결국 프로그램이라 CPU를 잡고 있어야 일을 하는데, CPU를 뺏겼으니 개입할 방법이 없습니다.
timer는 이 상황을 막습니다. 정해진 시간이 지나면 timer가 인터럽트를 걸고, CPU는 강제로 운영체제에 넘어갑니다. 그때 운영체제가 다른 프로그램에 CPU를 줄지 결정합니다. 타이머 값을 설정하는 것도 특권 명령입니다.
정리하면 timer는 특정 프로그램의 CPU 독점을 막는 장치이며, 시분할(time sharing) 구현의 기반입니다. 실제로 어떤 기준으로 다음 프로그램을 고르는지는 CPU 스케줄링 편에서 다룹니다.
입출력 장치는 CPU보다 훨씬 느립니다. CPU가 디스크의 회전을 기다리며 서 있으면 그만큼 손해입니다.
그래서 장치마다 device controller를 붙입니다. 해당 장치를 관리하는 작은 개별 CPU라고 보면 됩니다. 여기에 두 종류의 저장 공간이 붙습니다.
CPU가 "이 블록을 읽어라"라고 지시하면 controller가 데이터를 읽어 local buffer에 채웁니다. 그동안 CPU는 다른 일을 합니다. 다 채워지면 controller가 인터럽트로 CPU에 알립니다.
이름이 비슷한 device driver와 혼동하기 쉽습니다. device driver는 운영체제 안의 소프트웨어이고, device controller는 장치에 붙은 하드웨어입니다.
CPU는 명령 하나를 끝낼 때마다 interrupt line을 확인합니다. 신호가 들어와 있으면 하던 일을 멈추고 운영체제의 인터럽트 처리 루틴으로 넘어갑니다. 즉 CPU는 평소에 장치를 살피지 않고, 장치 쪽에서 필요할 때 신호를 올립니다.
인터럽트는 두 가지로 나뉩니다.
어느 쪽이든 CPU가 운영체제로 넘어간다는 결과는 같습니다. 여기서 무엇을 저장하고 어떻게 복귀하는지는 프로세스 편에서 다룹니다.
인터럽트로 문제가 다 풀린 것 같지만 새 문제가 생깁니다. controller가 데이터를 바이트 단위로 옮기면서 매번 인터럽트를 걸면 CPU가 인터럽트 처리만 하다 끝납니다.
작은 예제로 확인해 봅니다. 4KB 블록 하나를 디스크에서 메모리로 읽어옵니다.
CPU 개입이 4096번에서 1번으로 줄었습니다. 이것이 DMA(Direct Memory Access)의 목적입니다.
다만 이제 메모리에 접근하려는 주체가 CPU와 DMA controller 둘이 되었습니다. 동시에 접근하면 충돌하므로 memory controller가 순서를 정리합니다. 메모리 접근 요청을 받아 중재하고 순서대로 처리하는 역할입니다.
| 부품 | 없으면 생기는 문제 | 하는 일 | 특권 여부 |
|---|---|---|---|
| mode bit | 사용자 프로그램이 하드웨어를 직접 조작 | 사용자 모드(1) / 모니터 모드(0) 구분 | 변경이 특권 명령 |
| timer | 한 프로그램이 CPU 독점 | 일정 시간 후 인터럽트 발생 | 설정이 특권 명령 |
| device controller | CPU가 느린 장치를 직접 기다림 | 장치 하나를 전담 관리 | 하드웨어 |
| register | 제어 정보를 둘 곳이 없음 | 명령과 상태 저장 | 하드웨어 |
| local buffer | 데이터를 모아둘 곳이 없음 | 장치 데이터 임시 저장 | 하드웨어 |
| interrupt line | 장치가 CPU에 알릴 방법이 없음 | 완료 신호 전달 | 하드웨어 |
| DMA controller | 바이트 단위 인터럽트 폭주 | 메모리 직접 접근, 블록당 인터럽트 1회 | 하드웨어 |
| memory controller | CPU와 DMA의 메모리 접근 충돌 | 접근 순서 중재 | 하드웨어 |