운영체제란?
운영체제(Operating System, OS)에는 완벽하고 단일한 정의가 존재하지 않는다. 대략적으로 정리하면 다음과 같다.
- 사용자와 하드웨어 사이의 중개자(Intermediary)
- 커널(Kernel) + 추가 프로그램으로 구성
- 커널은 OS의 핵심으로, 항상 실행 중인 프로그램이다
- 시스템 프로그램이나 응용 프로그램은 커널에 포함되지 않는다
운영체제의 목표는 세 가지로 요약된다.
- 사용자 프로그램을 실행하고, 문제 해결을 쉽게 만든다
- 컴퓨터 시스템을 편리하게 사용할 수 있도록 한다
- 하드웨어를 효율적으로 활용한다
컴퓨터 시스템의 구성 요소

컴퓨터 시스템은 네 가지 구성 요소로 나눌 수 있다.
- 하드웨어(Hardware): 기본 컴퓨팅 자원을 제공한다 (CPU, 메모리, I/O 장치)
- 운영체제(Operating System): 다양한 응용 프로그램과 사용자 간에 하드웨어 사용을 제어하고 조정한다
- 응용 프로그램(Application Programs): 시스템 자원을 활용하여 사용자의 문제를 해결하는 방법을 정의한다 (워드 프로세서, 컴파일러, 웹 브라우저, 데이터베이스, 비디오 게임 등)
- 사용자(Users): 사람, 기계, 다른 컴퓨터
운영체제가 하는 일
운영체제의 역할은 크게 두 가지다.
환경 제공: OS 자체로는 유용한 기능을 수행하지 않는다. 그러나 OS가 제공하는 환경 위에서 사용자는 다양한 작업을 쉽게 수행할 수 있다.
시스템 자원 관리: 사용자와 프로그램이 시스템 자원을 시간적, 공간적으로 공유할 수 있게 하며, 하드웨어를 효율적으로 사용하도록 한다.
시스템 관점에서 본 OS
시스템 관점에서 운영체제는 두 가지 역할을 한다.
자원 할당자(Resource Allocator): CPU, 메모리, 파일 저장소, I/O 장치 등 모든 자원을 관리하며, 충돌하는 요청 사이에서 효율적이고 공정하게 자원을 분배한다.
제어 프로그램(Control Program): 프로그램 실행을 제어하여 오류와 컴퓨터의 부적절한 사용을 방지한다.
컴퓨터 시스템의 구조와 동작
컴퓨터 시스템의 부팅 과정
컴퓨터 전원이 켜지면 어떤 일이 일어날까?
- 부트스트랩 프로그램(Bootstrap Program, 펌웨어) 이 실행된다
- 시스템을 진단하고 초기화한다
- OS 커널을 메모리에 적재하고 실행한다 (Bootstrap Loader)
- OS 커널이 시작된다
- 초기화(init)를 수행한다
- 이벤트를 대기한다
- 이벤트를 처리한다
현대 운영체제는 인터럽트 기반(Interrupt-driven) 프로그램이다.
현대 컴퓨터 시스템

공통 버스(Common Bus) 는 컴퓨터 구성 요소 간에 데이터를 전송하는 서브시스템이다. CPU, 메모리, 장치 컨트롤러가 공통 버스로 연결되며, I/O 장치와 CPU는 동시에(concurrently) 실행될 수 있다.
각 장치 컨트롤러에는 로컬 버퍼(Local Buffer) 가 있다. 버퍼는 빠른 버스와 상대적으로 느린 I/O 장치 사이에서 속도를 조절하는 역할을 한다.
CPU는 메인 메모리와 로컬 버퍼 사이에서 데이터를 이동시킨다. I/O는 장치에서 컨트롤러의 로컬 버퍼로 수행된다. 장치 컨트롤러는 작업이 완료되면 인터럽트(Interrupt) 를 발생시켜 CPU에 알린다. 덕분에 CPU는 I/O 작업을 기다리지 않고 다른 작업을 수행할 수 있다.
인터럽트 (Interrupt)

인터럽트는 하드웨어 또는 소프트웨어에서 발생하는 비동기 신호(Asynchronous Signal) 로, 처리가 필요한 상황을 알린다.
- 하드웨어가 지원한다
- 각 인터럽트 유형은 고유한 번호(IRQ 번호)와 연결된다
인터럽트를 처리하기 위해 각 유형별로 어떤 동작을 수행할지 정의하는 코드가 존재한다.
- 인터럽트 벡터(Interrupt Vector): 인터럽트 핸들러들의 주소가 저장된 테이블
- 이벤트를 처리하는 메커니즘으로, 다음과 같이 분류된다
- 하드웨어 인터럽트
- 소프트웨어 인터럽트
- 시스템 콜(System Call) = 모니터 콜: 프로그램에서 OS로의 요청
- 예외(Exception)
CPU의 실행 사이클
CPU 실행 사이클을 이해하기 위한 주요 용어는 다음과 같다.
- PC(Program Counter): 다음에 실행할 명령어의 주소를 저장
- IRQ(Interrupt Request): 인터럽트 요청 번호
- ISR(Interrupt Service Routine): 인터럽트 핸들러
InterruptRequest = FALSE;
…
while(haltFlag not set during execution) {
IR = memory[PC];
PC++;
execute(IR);
if(InterruptRequest) { // Interrupt the current process
save_PC(); // Save the PC
restore_PC(IRQ); // Branch to the ISR for this IRQ
}
}
핸들러로 점프하기 위해 PC에 핸들러의 위치를 넣는데, 이 위치는 인터럽트 벡터에 저장되어 있다.
인터럽트 처리 메커니즘

인터럽트가 발생하면 다음 순서로 처리된다.
- CPU가 현재 작업을 중단하고, 해당 인터럽트 핸들러로 실행을 전환한다
- 해당 핸들러가 인터럽트를 처리한다
- 원래 중단되었던 프로그램으로 복귀한다
인터럽트 핸들러가 호출되기 전에, 복귀 주소(Return Address) 와 상태(State) 등 필요한 정보를 반드시 저장해야 한다.
인터럽트 기반 I/O

- CPU가 I/O 요청을 보내고 현재 프로세스를 계속 실행하거나 다른 작업을 수행한다
- 데이터 전송이 완료되면 I/O 장치가 인터럽트를 발생시킨다
메인 메모리
레지스터(Register) 는 CPU 내부에 위치한 작고 빠른 메모리다.
메인 메모리(Main Memory) 는 데이터나 명령어를 저장하는 셀(Cell)의 배열로, 각 셀은 고유한 주소로 식별된다. 빠르지만 휘발성(Volatile), 즉 전원이 꺼지면 데이터가 사라진다.
모든 형태의 메모리는 바이트 배열을 제공하며, 각 바이트에는 고유한 주소가 있다. load와 store 연산에서는 대상과 주소가 핵심이다.
저장 장치 계층 구조


I/O 장치 접근 방식

I/O 장치 접근 방식은 시대에 따라 발전해 왔다.
구형 시스템: Busy Waiting

CPU가 장치 상태를 주기적으로 확인(Polling) 하는 방식이다. 문제는 CPU가 I/O 장치를 기다리는 동안 아무것도 하지 못한다는 점이다. 가장 중요하고 비싼 자원인 CPU를 낭비하게 된다.
현대 시스템: 인터럽트 기반 I/O

CPU가 컨트롤러에 요청을 보내면, I/O 작업이 완료되었을 때 인터럽트로 CPU에 알린다. 필요한 경우 CPU가 I/O 작업에 대한 정보를 요청할 수 있다. 하지만 대용량 데이터를 메모리로 이동시키는 전송(transfer) 과정에는 여전히 CPU가 관여해야 한다는 문제가 있다.
DMA (Direct Memory Access)

대용량 데이터 전송을 위한 해결책이 DMA다. 장치 컨트롤러가 CPU의 관여 없이 대용량 데이터를 메인 메모리에 직접 전송한다. CPU는 데이터 전송에 관여하지 않아도 되므로 그동안 다른 작업을 수행할 수 있다.
컴퓨터 시스템 구조
단일 프로세서 시스템 (Single-Processor System)
단일 범용(General-purpose) CPU를 사용하는 시스템이다. 장치 컨트롤러의 프로세서 등 특수 목적 프로세서가 존재할 수 있지만, 이들은 사용자 프로세스를 위한 것이 아니다.
장점은 단순하고 저렴하다는 점이다.
멀티프로세서 시스템 (Multi-Processor System)
두 개 이상의 프로세서가 긴밀하게 통신하는 시스템으로, 밀결합(Tightly-coupled) 시스템이라고도 한다. 버스, 클럭, 메모리, 주변 장치를 공유한다.
일반적으로 멀티코어 시스템도 이 범주에 포함된다. 멀티코어는 칩은 하나인데 코어가 여러 개인 구조로, 코어들이 캐시 메모리를 공유할 수 있다.

멀티프로세서 시스템은 다음과 같이 분류된다.

- 대칭형 멀티프로세싱(SMP, Symmetric Multiprocessing): 모든 프로세서가 동등(peer)한 관계
- 비대칭형 멀티프로세싱(Asymmetric Multiprocessing): CPU 종류가 다른 경우에 해당하며, Master-Slave 관계로 마스터가 슬레이브를 스케줄링하고 할당한다
멀티프로세서 시스템의 장점은 다음과 같다.
- 처리량(Throughput) 증가: 이상적인 경우 N개의 프로세서로 N배 향상되지만, 실제로는 오버헤드가 존재한다. 단순 속도 향상이 아닌 단위 시간당 처리량의 증가를 의미한다.
- 신뢰성(Reliability) 향상
- 규모의 경제: 클러스터 시스템에 비해 메모리, 주변 장치 등을 공유할 수 있어 비용이 절약된다
클러스터 시스템 (Clustered System)

클러스터 시스템은 소결합(Loosely-coupled) 시스템으로, 네트워크로 연결된 여러 시스템이 함께 동작한다. 밀결합 시스템(멀티프로세서)과 달리 버스, 메모리, 클럭을 공유하지 않는다.
일반적으로 SAN(Storage-Area Network) 을 통해 스토리지를 공유한다. SAN은 통합된 블록 수준 데이터 스토리지에 대한 접근을 제공하는 전용 네트워크로, 스토리지 장치가 OS에게 로컬에 연결된 것처럼 보이도록 한다. SAN은 호스트, 스위치, 스토리지 요소로 구성된다.

클러스터 시스템은 고가용성(High-Availability) 서비스를 제공하여 장애를 극복한다.
- 비대칭 클러스터링(Asymmetric Clustering): 한 머신이 상시대기(hot-standby) 모드로 대기
- 대칭 클러스터링(Symmetric Clustering): 여러 노드가 애플리케이션을 실행하면서 서로를 모니터링. 한쪽에 장애가 발생해도 나머지가 동작한다
- Graceful Degradation: 일부에 장애가 발생해도 나머지가 계속 동작하는 특성
- Fault Tolerant: 기능적 손해가 있을 수 있지만, 전체 시스템에 문제가 생겨도 최소한 일부는 동작한다
일부 클러스터는 고성능 컴퓨팅(HPC, High-Performance Computing) 을 위해 사용되며, 이 경우 애플리케이션이 병렬화를 활용하도록 작성되어야 한다.
충돌하는 연산을 방지하기 위해 분산 잠금 관리자(DLM, Distributed Lock Manager) 를 사용하는 클러스터도 있다. 여러 컴퓨터가 동시에 접근하지 못하도록, 한 컴퓨터가 쓰기(write) 작업을 할 때 다른 컴퓨터의 접근을 잠그는 역할을 한다.
운영체제의 구조와 동작
단일 사용자만으로는 CPU와 I/O 장치를 항상 바쁘게 유지할 수 없다. 이것이 멀티프로그래밍과 멀티태스킹이 필요한 이유다.
멀티프로그래밍 (Multiprogramming)

멀티프로그래밍은 프로세서가 입출력 작업의 종료를 대기하는 동안 다른 프로그램을 수행할 수 있도록 하는 기법이다.
- 여러 작업(코드와 데이터)을 조직화하여 CPU가 항상 실행할 작업이 있도록 한다
- 전체 작업 중 일부를 메모리에 유지한다
- 작업 스케줄링(Job Scheduling) 을 통해 하나의 작업을 선택하여 실행한다
- 작업이 대기해야 하는 상황이 되면 OS가 다른 작업으로 전환한다
시분할 (Timesharing, Multitasking)

시분할은 멀티프로그래밍의 논리적 확장이다. CPU가 작업을 매우 빈번하게 전환하여 사용자가 각 작업과 상호작용할 수 있는 대화식(Interactive) 컴퓨팅을 구현한다. 스위칭 오버헤드로 인해 전환할 때마다 약간의 딜레이가 발생한다.
- 필요하지 않은 상황에서도 스위칭을 수행한다
- 응답 시간(Response Time) 은 1초 미만이어야 한다
- 각 사용자는 메모리에서 실행 중인 프로그램(프로세스)을 최소 하나 갖는다
- CPU 스케줄러(CPU Scheduler) 가 실행 준비가 된 작업을 선택한다
멀티프로그래밍 vs. 멀티태스킹
멀티프로그래밍은 프로세서의 자원 낭비를 방지하기 위한 것이고, 멀티태스킹은 정해진 시간 동안 각각의 태스크를 번갈아가며 수행하는 것을 의미한다.
가상 메모리 (Virtual Memory)

멀티프로그래밍/멀티태스킹 시스템에서 메인 메모리만으로는 모든 프로세스를 수용하기 어렵다. 이를 해결하기 위한 방법이 있다.
- 스와핑(Swapping): 메모리 내용을 디스크에서 메모리로(Disk->Mem), 메모리에서 디스크로(Mem->Disk) 이동시켜 실행한다
- 가상 메모리(Virtual Memory): 프로세스 전체가 메모리에 없어도 실행을 가능하게 한다
가상 메모리는 응용 프로그램에게 연속적인(Contiguous) 작업 메모리가 있는 것처럼 보이게 하는 기법이다. 실제로는 물리적으로 조각나 있으며(Fragmented), 일부는 디스크 스토리지로 넘칠 수도 있다. 간단히 말하면, "디스크 공간을 사용하여 물리 메모리 크기를 확장"하는 기법이다.
운영체제의 동작
현대 OS는 인터럽트 기반 프로그램으로, 이벤트는 인터럽트로 전달되고 인터럽트 핸들러가 이를 처리한다. 하드웨어와 소프트웨어 자원이 공유되기 때문에 하나의 프로세스 오류가 전체 시스템을 손상시킬 수 있다는 문제가 존재한다.
다중 사용자 OS의 필수 요구사항은 하나의 프로그램 오류가 다른 프로그램에 영향을 주지 않아야 한다는 것이다. 이를 위해 두 가지 방어 메커니즘이 사용된다.
- 위험한 명령어에 대한 대응: 듀얼 모드 동작(Dual-mode Operation)
- 지나치게 긴 실행에 대한 대응: 타이머 인터럽트(Timer Interrupt)
듀얼 모드 동작 (Dual-mode Operation)
듀얼 모드 동작은 하드웨어 지원이 필요하다.
사용자 모드 (User Mode)
사용자가 정의한 코드(응용 프로그램)가 실행되는 모드다. super-user(sudo)도 사용자 모드에서 실행된다.
이 모드에서는 특권 명령어(Privileged Instructions) 가 금지된다. 특권 명령어란 잘못 사용할 경우 다른 시스템에 피해를 줄 수 있는 명령어로, I/O 명령어, 타이머 명령어 등이 해당한다. 특권 명령어는 오직 OS 시스템 콜을 통해서만 호출할 수 있다.
만약 사용자 모드에서 특권 명령어를 실행하면? 인터럽트가 발생하고, 인터럽트 핸들러로 점프한 뒤 커널이 해당 프로세스를 종료(terminate)시킨다.
커널 모드 (Kernel Mode)
supervisor mode, system mode, privileged mode라고도 한다. OS 코드가 실행되며, 특권 명령어의 실행이 허용된다.

듀얼 모드 동작의 장점은 모드를 위반하는 오류를 하드웨어가 감지하고 OS가 처리할 수 있다는 점이다. 시스템 전체가 멈추는 것이 아니라 해당 프로세스만 비정상 종료되며, 오류 메시지를 출력하고 메모리를 덤프한다.
타이머 인터럽트 (Timer Interrupt)

프로그램의 지나치게 긴 실행을 방지하기 위한 메커니즘이다. OS가 사용자 프로세스에 제어권을 넘기기 전에, 미리 정의한 시간 후에 인터럽트가 발생하도록 타이머를 설정한다. 타이머 인터럽트가 발생하면 OS가 제어권을 다시 가져와 적절하게 처리한다.
타이머 카운터는 특권 명령어로만 수정할 수 있다.
멀티 모드 동작 (Multi-mode Operation)
현대 시스템은 두 모드를 넘어 여러 보호 링(Ring)을 사용하기도 한다.
- Ring 0: 커널 모드
- Ring 1, 2: 가상 머신용
- Ring 3: 사용자 모드
OS의 핵심 구성 요소
프로세스 관리 (Process Management)
프로세스는 OS가 관리하는 가장 중요한 자원이다.
프로세스(Process) 란 실행 중인 프로그램, 즉 활성(Active) 엔티티를 의미한다. 실행되지 않는 프로그램은 디스크에 저장된 단순한 파일에 불과하다.
- 필요한 자원을 가진 활성 프로그램이다 (예: PC에서 실행 중인 워드 프로세서)
- 단일 스레드 프로세스는 하나의 프로그램 카운터(Program Counter) 를 가진다
- 하나의 프로그램에서 여러 인스턴스를 실행하면, 각각이 별도의 프로세스가 된다
- 작업의 단위로서, OS 프로세스와 사용자 프로세스로 나뉜다
프로세스와 유사한 용어
1. 스레드(Thread)
하나의 프로그램이 두 개 이상의 동시 실행 작업으로 분리되는 방식이다. 예를 들어, PPT에서 인쇄와 편집을 동시에 수행하는 것이 해당한다.
- CPU 활용의 기본 단위
- 프로세스보다 작은 단위
- 각 스레드는 고유한 ID, 프로그램 카운터, 레지스터 세트, 스택을 가진다
- 주요 자원은 공유한다 (같은 프로세서, 멀티 스레드)
2. 태스크(Task)
주소 공간을 통한 실행 경로를 의미하며, 프로세스와 스레드를 구분하지 않는다. 메모리에 적재된 프로그램 명령어의 집합으로, Linux 등의 컨텍스트에서는 프로세스 또는 프로세스와 스레드 모두를 의미한다.
OS의 프로세스 관리 기능

OS는 프로세스에 자원을 할당하며 다음과 같은 관리 기능을 수행한다.
- 프로세스의 생성(할당)과 삭제(해제)
- 프로세스의 일시 중지(Suspend)와 재개(Resume)
- 프로세스 동기화(Synchronization): 궁극적인 목적은 문제 발생을 예방하는 것

- 프로세스 통신(Communication): 두 개 이상의 프로세스가 협력할 때 자원이 공유되지 않기 때문에 OS의 특별한 통신 장치가 필요하다
- 교착 상태(Deadlock) 처리
메모리 관리 (Memory Management)
메모리는 OS가 관리하는 두 번째로 중요한 자원이다.
메인 메모리는 현대 시스템 동작의 핵심이다. CPU가 직접 주소를 지정하고 접근할 수 있는 유일한 대용량 저장소이며, CPU와 I/O 장치가 공유하는 데이터의 저장소 역할을 한다.
OS의 메모리 관리 기능은 다음과 같다.
- 메모리의 어떤 부분이 누구에 의해 점유되고 있는지 추적 (이중 할당 방지)
- 메모리 공간의 할당/해제
- 어떤 프로세스와 데이터를 메모리에 넣고 뺄지 결정 (스와핑)
스토리지 관리 (Storage Management)

물리적 저장 장치(자기 디스크, 광학 디스크, 자기 테이프 등)를 논리적 파일(File) 로 추상화하는 것이 스토리지 관리의 핵심이다. 물리적 저장 장치는 속도, 용량, 전송률, 접근 방식이 다양하며, 파일은 OS가 추상화한 논리적 저장 단위다.
참고로 Device Driver는 소프트웨어이고, Device Controller는 하드웨어다. 디바이스 드라이버는 다양한 장치에 대해 균일한 인터페이스를 제공한다.

파일 시스템 관리는 다음을 포함한다.
- 파일과 디렉터리의 생성/삭제
- 파일/디렉터리 조작을 위한 기본 연산(Primitives) 지원
- 파일을 보조 저장 장치에 매핑
- 안정적인 저장 매체에 파일 백업
캐싱 (Caching)

캐싱은 사용된 정보의 임시 복사본을 더 작고 빠른 저장소에 저장하여 다음 접근을 빠르게 하는 기법이다. 참조의 지역성(Locality of References) 에 기반한다.
특정 정보가 필요할 때의 동작 순서는 다음과 같다.
- 먼저 캐시에 있는지 확인한다 (원본 소스보다 빠르다)
- 있으면 캐시에서 사용하고, 없으면 원본 소스에서 가져온다
참고로, 메인 메모리도 보조 메모리의 캐시로 볼 수 있다.
캐시 일관성 (Cache Coherence)

멀티프로세서 환경에서는 캐시 일관성(Cache Coherence) 을 하드웨어적으로 보장해야 한다. 모든 CPU가 캐시에서 가장 최신 값을 가지고 있어야 한다.
캐시 일관성이란, 공유 자원의 로컬 캐시에 저장된 데이터의 무결성(Integrity) 을 의미한다.
보호와 보안 (Protection and Security)

다중 사용자, 다중 처리 시스템에서 보호와 보안은 핵심 이슈다. 파일, 메모리 세그먼트, CPU, 기타 자원에 대한 권한 부여 메커니즘이 필요하다.
보호(Protection) 는 프로세스나 사용자의 자원 접근을 제어하는 모든 메커니즘을 의미한다. 모든 프로세스와 자원에 고유한 User ID, Group ID를 할당하여 ID가 다르면 접근을 차단하는 방식으로 동작한다.
그러나 보호만으로는 충분하지 않다. 인증(Authentication)이 도용될 수 있기 때문이다.
보안(Security) 은 인증을 불법적으로 획득하려는 외부/내부 공격에 대한 방어를 의미한다. 현대 컴퓨팅 환경에서 보안 이슈는 매우 중요하다.
HGU 전산전자공학부 김인중 교수님의 23-1 운영체제 수업을 듣고 작성한 포스트이며, 첨부한 모든 사진은 교수님 수업 PPT의 사진 원본에 필기를 한 수정본입니다.