Search
Duplicate

운영체제/ 서론

운영체제(operating system)은 컴퓨터 하드웨어를 관리하는 프로그램으로 응용 프로그램을 위한 기반을 제공하며 컴퓨터 사용자와 컴퓨터 하드웨어 사이에서 중재자 역할을 수행한다.

운영체제가 할 일

컴퓨터 시스템은 대개 네 가지 구성 요소인 하드웨어, 운영체제, 응용 프로그램 및 사용자로 구분할 수 있다. (그림 1.1)
하드웨어는 중앙 처리 장치(CPU), 메모리, 입출력(I/O) 장치로 구성되어 기본 계산용 자원을 제공한다.
응용 프로그램인 워드 프로세서, 스프레드시트, 컴파일러, 웹브라우저 등은 사용자의 계산 문제를해결하기 위해 이들 자원이 어떻게 사용될지를 정의한다.
운영체제는 다양한 사용자를 위해 다양한 응용 프로그램간의 하드웨어 사용을 제어하고 조정한다.
또한 우리는 컴퓨터 시스템이 하드웨어, 소프트웨어 및 데이터로 구성되어 있다고 볼 수 있다. 운영체제는 컴퓨터 시스템이 동작할 때 이들 자원을 적절하게 사용할 수 있는 방법을 제공한다.
운영체제는 정부(goverment)와 유사하다. 운영체제는 정부처럼 그 자체로는 유용한 기능을 수행하지 못한다. 운영체제는 단순히 다른 프로그램이 유용한 작업을 할 수 있는 환경을 제공한다.

사용자 관점(User View)

컴퓨터에 대한 사용자의 관점은 사용되는 인터페이스에 따라 달라진다.
대부분의 컴퓨터 사용자는 모니터, 키보드, 마우스 및 시스템 유닛으로 구성된 PC 앞에서 작업을 하는데, 이런 경우 시스템은 한 사용자가 자원을 독점하도록 설계되었으며 목표는 사용자가 수행하는 작업을 최대화하는 것이다.
다른 경우 사용자는 대형 컴퓨터나 미니 컴퓨터에 연결된 터미널에 앉아 있는 경우도 있다. 다른 사용자들은 동일한 컴퓨터를 다른 터미널에 접근하고 있다. 이들 사용자들은 자원을 공유하며 정보를 교환할 수도 있다. 이 경우 운영체제는 자원 이용을 극대화하도록 설계되어 있어 모든 가용 CPU 시간, 메모리 및 입출력은 효율적으로 사용되며 각 개인은 자신의 정당한 몫만 사용할 수 있다.
또 다른 경우 사용자는 워크스텡션과 서버의 네트워크에 연결된 워크스테이션에 앉아 있는 경우가 있는데, 이들 사용자들은 자신이 마음대로 할 수 있는 전용 자원을 갖지만 이들은 또한 네트워킹과 서버-파일, 계산 및 프린트 서버를 공유한다. 따라서 운영체제는 개인의 사용 용이성과 자원 이용 간에 적절히 조화를 이루도록 설계되어 있다.
(이하 생략)

시스템 관점(System View)

컴퓨터의 고나점에서 운영체제는 하드웨어와 가장 밀접하게 연관된 프로그램이다. 따라서 우리는 운영체제를 자원 할당자(resource allocator)로 볼 수 있다.
컴퓨터 시스템은 문제를 해결하기 위해 요구되는 여러 자원들(하드웨어와 소프트웨어) 즉, CPU 시간, 메모리 공간, 파일 저장 공간, 입출력 장치 등을 가진다.
운영체제는 이들 자원의 관리자로서 동작하며, 작업을 위해 특정 프로그램과 사용자에 필요한 자원을 할당한다. 자원에 대해 서로 상충될 수 있는 많은 요청이 있기 때문에 운영체제는 컴퓨터 시스템을 효율적이고 공정하게 운영 할 수 있도록 어느 요청에 자원을 할당할지를 결정해야 한다.
운영체제에 대한 다소 다른 관점은 여러 가지 입출력 장치와 사용자 프로그램을 제어할 필요성을 강조한다. 운영체제는 제어 프로그램(control program)이다. 제어 프로그램은 컴퓨터의 부적절한 사용을 방지하기 위해 사용자 프로그램의 수행을 제어한다. 운영체제는 특히 입출력 장치와 제어와 작동에 깊이 관여한다.

운영체제의 정의

(생략)

컴퓨터 시스템의 구성

컴퓨터 시스템 연산(Computer-System Operation)

현대의 범용 컴퓨터 시스템은 공유 메모리에 대한 접근을 제공하는 공통 버스에 의해 연결된 여러 개의 장치 제어기와 하나 이상의 CPU로 구성되어 있다. (그림 1.2)
각 장치 제어기는 특정 장치를 관리하고 있다.
CPU와 장치 제어기는 메모리 사이클을 얻기 위해 경쟁하면서 병렬 수행될 수 있다. 공유 메모리에 대한 질서 있는 접근을 보장하기 위해, 메모리 제어기가 제공되며, 그것의 기능은 메모리 접근을 동기화 시키는 일이다.
컴퓨터가 구동을 시작하기 위해서는 수행할 초기 프로그램을 가져야 한다.
이 초기 프로그램(또는 부트스트랩 프로그램: bootstrap program) 은 매우 단순한 경향이 있다. 전형적으로 이것은 보통 펌웨어라고 알려져 있는 컴퓨터 내의 읽기 전용 메모리(ROM, Read-Only Memory)나 EEPROM에 저장된다. 이것은 CPU 레지스터로부터 장치 제어기, 메모리 내용 등을 포함한 시스템의 모든 면을 초기화한다.
또한 부트스트랩 프로그램은 운영체제를 적재하는 방법 및 수행을 시작하는 방법을 알아야 한다. 이러한 목적을 달성하기 위해 부트스트랩 프로그램은 운영체제의 커널을 찾아 메모리에 적재해야 한다.
커널이 적재되고 수행이 싲가되면 시스템과 사용자에게 서비스를 제공할 수 있다. 일부 서비스는 커널이 아닌 시스템 프로그램에 의해 제공되며 이들은 부트 시에 메모리에 적재되어 커널이 수행되는 동안 계속 수행되는 시스템 프로세서나 시스템 디먼이 된다.
유닉스에서는 첫 시스템 프로세스가 init이며 init가 다른 많은 디먼을 시작한다.
이 단계가 끝나면 시스템이 완전히 부트된 상태이며 시스템은 무슨 사건(event)이 발생하기를 기다린다.
사건이 발생하면 하드웨어나 또는 소프트웨어로부터 발생한 인터럽트(interrupt)에 의해 신호가 보내진다. 하드웨어는 어느 순간이든 시스템 버스를 통해 CPU에 신호를 보내 인터럽트를 발생시킬 수 있다. 소프트웨어는 시스템 호출(system call, 또는 모니터 호출)이라 불리는 특별한 연산을 실행하여 인터럽트를 발생시킬 수 있다.
CPU가 인터럽트 되면 CPU는 하던 일을 중단하고 즉시 고정된 위치로 실행을 옮긴다. 이러한 고정된 위치는 일반적으로 인터럽트를 위한 서비스 루틴이 위치한 시작 주소를 가지고 있다. 그리고 인터럽트 서비스 루틴이 실행된다.
인터럽트 서비스 루틴의 실행이 완료되면 CPU는 인터럽트 되었던 연산을 재개한다. 이러한 연산의 시간 일정(time line)이 그림 1.3에 있다.
인터럽트는 컴퓨터 구조의 중요한 부분이다. 각 컴퓨터 설계는 자신의 인터럽트 메커니즘을 가지고 있으며, 몇 가지 기능은 공통적이다. 인터럽트는 적절한 서비스 루틴으로 제어를 전달한다.
이러한 전달을 처리하는 직선적인 방법은 인터럽트 정보를 조사하는 일반적인 루틴을 호출하는 방법이다. 이 루틴은 이어 인터럽트 고유의 핸들러(handler)를 호출한다.
그러나 인터럽트는 매우 빠르게 처리되어야 하고, 사용 가능한 인터럽트의 수가 미리 정의되어 있으므로 대신 인터럽트 루틴에 대한 포인터들의 테이블을 이용할 수 있다. 이 경우 중단 루틴을 둘 필요 없이 테이블을 통하여 간접적으로 인터럽트 루틴이 호출될 수 있다.
일반적으로 포인터들의 테이블은 하위 메모리에 저장된다(첫 100개 정도의 위치). 이들 위치에는 여러 장치에 대한 인터럽트 서비스 루틴의 주소가 들어 있다.
인터럽트가 요청되면 인터럽트를 유발한 장치를 위한 인터럽트 서비스 루틴의 주소를 제공하기 위해 이 주소의 배열 즉, 인터럽트 벡터가 인터럽트 요청과 함께 주어진 고유의 유일한 장치 번호로 색인된다. Windows나 UNIX 같은 서로 다른 운영체제가 이러한 방법으로 인터럽트를 처리한다.
또한 인터럽트 구조는 인터럽트된 명령의 주소를 반드시 저장해야 한다. 많은 과거의 설계는 고정 위치에 인터럽트 주소를 저장하거나 장치 번호에 의해 색인되는 위치에 저장하였다. 최근의 구조들은 시스템 스택에 복귀 주소를 저장한다.
만약 인터럽트 루틴이 처리기의 상태를 변경할 필요(예컨대 레지스터의 값을 변경하여)가 있다면 인터럽트 루틴은 반드시 명시적으로 현재의 상태를 저장하여야 하며, 복귀하기 전에 상태를 복원해야 한다.
인터럽트를 서비스한 후, 저장되어 있던 복귀 주소를 프로그램 카운터에 적재하고, 인터럽트에 의해 중단되었던 연산이 인터럽트가 발생되지 않았던 것처럼 다시 시작된다.

저장 장치 구조(Storage Structure)

CPU는 단지 명령어를 메모리로부터 가져올 수 있으므로 프로그램을 수행하려면 프로그램이 반드시 메모리에 있어야 한다.
범용 컴퓨터는 대부분의 프로그램을 주 메모리(Random-Access Memory, RAM)라 불리는 재기록 가능한 메모리에서 가져온다. 주 메모리는 Dynamic Random-Access Memory(DRAM)라 불리는 반도체 기술로 구현된다.
컴퓨터는 다른 형태의 메모리도 사용한다. 읽기 전용 메모리인 ROM과 전기적으로 소거 가능한 프로그램 가능-읽기 전용 메모리 EEPROM 등이 있다. ROM은 변경할 수 없으므로 앞서 설명한 부트스트랩 프로그램과 같은 정적 프로그램을 저장한다. ROM의 불변성은 게임 카트리지에 유용하다. 스마트폰은 공장에서 설치한 프로그램을 저장하기 위해 EEPROM을 사용한다.
모든 형태의 메모리는 바이트 배열을 제공한다. 각 바이트는 자신의 주소를 가지고 있다. 상호 작용은 특정 메모리 주소들에 대한 일련의 적재(load) 또는 저장(store) 명령을 통해 이루어진다.
적재 며령은 주 메모리로부터 CPU 내부의 레지스터로 한 바이트 또는 한 워드를 옮기는 것이고, 저장 명령은 레지스터의 내용을 주 메모리로 옮긴다.
명시적인 적재, 저장 명령 외에 CPU는 실행을 위해 자동적으로 주 메모리로부터 명령을 적재한다.
폰 노이만 구조 시스템에서 실행되는 전형적인 명령-실행 사이클은 먼저 메모리로부터 명령을 인출해, 그 명령을 명령 레지스터(instruction register)에 저장한다.
이어서 명령을 해독하고 이는 메모리로부터 피연산자를 인출하여 내부 레지스터에 저장하도록 유발할 수 있다. 피연산자에 대해 명령을 실행한 후에 결과가 메모리에 다시 저장될 수 있다.
메모리 장치는 단지 일련의 메모리 주소만을 인식한다는 사실에 유의하라. 메모리는 이들 주소(명령 카운터(instruction counter), 색인(indexing), 간접 주소(indirection), 리터럴 주소(literal addresses) 등)가 어떻게 생성되었는지 알지 못하며, 그것이 무엇인지 알지 못한다.
그러므로 우리는 메모리 주소가 프로그램에 의해 어떻게 생성되었는지 무시할 수 있다. 우리는 단지 실행 중인 프로그램에 의해 생성된 일련의 메모리 주소에만 흥미가 있다.
이상적으로 프로그램과 데이터가 주 메모리에 영구히 존재하기를 원하지만 다음 두 가지 이유로 불가능하다.
1.
주 메모리는 모든 필요한 프로그램과 데이터를 영구히 저장하기에는 너무 작다.
2.
주 메모리는 전원이 공급되지 않으면 그 내용을 잃어버리는 휘발성 저장 장치이다.
그러므로 대부분의 컴퓨터 시스템은 주 메모리의 확장으로 보조 저장 장치를 제공한다. 보조 저장 장치의 주요 요건은 대량의 데이터를 영구히 보존할 수 있어야 한다는 점이다.
가장 일반적인 보조 저장 장치로는 프로그램과 데이터 모두를 저장할 수 있는 자기 디스크이다. 대부분의 프로그램은 메모리에 적재될 때까지 디스크에 저장된다. 그리고 많은 프로그램들이 처리를 위한 정보의 원천과 목적지로 디스크를 사용한다.
그러나 큰 관점에서 우리가 기술한 이러한 저장 장치 구조(레지스터, 주 메모리, 자기 디스크 등으로 구성된)는 여러 가능한 저장 장치 시스템 중 하나이다. 이외에도 캐시 메모리, CD-ROM, 자기 테이프 등이 있다.
컴퓨터 시스템에서 저장 장치 시스템의 넓은 다양성은 속도와 가격에 따라 하나의 계층으로 구성될 수 있다. (그림 1.4) 상위 수준은 가격이 비싸지만 빠르다. 계층 구조의 아래로 갈 수록 비트당 비용은 일반적으로 감소하며, 반면 접근 시간은 일반적으로 증가한다.
(이하 생략)

입출력 구조(I/O Structure)

저장 장치는 컴퓨터 내의 여러 형태의 입출력 장치 중 하나이다. 시스템의 신뢰성과 성능에 미치는 중요성 때문에 그리고 장치의 다양한 특질 때문에 운영체제 코드의 많은 부분들이 입출력을 관리하는데 할애된다.
범용 컴퓨터 시스템은 공통 버스에 의해 연결된 여러 개의 장치 제어기와 CPU들로 구성되어 있다. 각 장치 제어기가 특정 타입의 장치를 담당한다. 장치 제어기에 따라 하나 이상의 장치가 부착될 수도 있다. 예컨대 SCSI(Small Computer Systems Interface) 제어기에는 7개 이상의 장치를 붙일 수 있다.
장치 제어기는 약간의 로컬 버퍼 저장 장치와 특수 목적용 레지스터 집합을 유지한다. 장치 제어기는 자신이 제어하는 주변 장치와 자신의 로컬 버퍼 저장 장치 사이의 데이터 전송을 담당한다.
통상적으로 운영체제는 각 장치 제어기마다 디바이스 드라이버를 가지고 있다. 이 디바이스 드러이버는 장치 제어기의 동작을 이해하고 운영체제의 다른 부분들에게 장치에 대한 일관된 인터페이스를 제공한다.
입출력 연산을 시작하기 위해 디바이스 드라이버는 장치 제어기의 적절한 레지스터에 필요한 값을 적재한다. 장치 제어기는 이어 취할 동작 (예컨대 ‘키보드에서 한 문자를 읽어라’)을 결정하기 위해 이들 레지스터의 내용을 조사한다.
제어기는 장치로부터 자신의 로컬 버퍼로 데이터 전송을 시작한다. 일단 데이터 전송이 완료되면 장치 제어기는 자신이 연산을 완료했음을 인터럽트를 이용하여 디바이스 드라이버에 통보한다.
그러면 디바이스 드라이버는 제어를 운영체제에 반환하고 이때 입력 완료인 경우에는 데이터 또는 데이터에 대한 포인터를 같이 반환할 수도 있다. 다른 동작에 대해서는 디바이스 드라이버는 상태 정보를 반환한다.
이 인터럽트 구동 방식의 입출력은 적은 양의 데이터를 전송하는데는 문제가 없으나 디스크 입출력과 같은 대량의 데이터를 전송하는데는 높은 오버헤드를 초래한다. 이 문제를 해결하기 위해 직접 메모리 접근(Direct Memory Access, DMA) 장치가 사용된다.
장치에 대한 버퍼 및 포인터, 입출력 카운트를 세팅한 후 장치 제어기는 CPU의 개입 없이 메모리로부터 자신의 버퍼 장치로 또는 버퍼로부터 메모리로 데이터 블록 전체를 전송한다.
속도가 느린 장치처럼 한 바이트마다 인터럽트가 발생하는 것이 아니라 블록 전송이 완료될 때마다 인터럽트가 발생한다. 장치 제어기가 전송 작업을 수행하고 있는 동안 CPU는 다른 작업을 수행할 수 있다.
몇몇 고가의 시스템은 버스 대신에 스위치 구조를 사용한다. 이러한 시스템에서는 공유 버스를 사용하기 위한 사이클을 경쟁하지 않고 다수의 구성요소들이 달느 구성요소들과 동시에 통신하는 것이 가능하다. 이 경우 DMA의 사용은 더욱 효과적이다. 그림 1.5는 컴퓨터 시스템의 구성요소 간의 상호 작용을 보여준다.

컴퓨터 시스템의 구조

단일 처리기 시스템(Single-Processor Systems)

최근까지 대부분의 시스템은 하나의 처리기를 사용했다. 단일 처리기 시스템은 사용자 프로세스의 명령어를 포함하여 범용 명령어 집합을 수행할 수 있는 하나의 주 CPU를 가진다.
또한 거의 대부분의 시스템들이 특수 목적의 전용 처리기를 가지고 있다. 이 전용 처리기는 디스크나 키보드 또는 그래픽 제어기와 같은 특정 장치 처리기의 형태로 제공되거나 메인 프레임에서와 같이 시스템의 구송요소들 간의 데이터를 빠르게 전송할 수 있는 입출력 처리기와 같은 범용 처리기에 가까운 형태로 제공될 수도 있다.
이 모든 전용 처리기들은 제한된 명령어 집합을 실행하고 사용자 프로세스를 실행하지 않는다. 때로 이 처리기들은 운영체제에 의해 관리되기도 하는데 운영체제는 이 처리기들이 수행할 다음 태스크에 대한 정보를 보내고 처리기들의 상태를 감시한다.
예컨대 디스크 제어기 마이크로프로세서는 주 CPU로부터 연속된 요청을 받아들여 자기 고유의 디스크 큐와 스케줄링 알고리즘을 구현한다. 이 배합은 CPU가 직접 디스크 스케줄링을 해야 하는 오버헤드를 감소시킨다. PC의 키보드는 키스트로크를 CPU에 전송할 코드로 변환하는 마이크로프로세서를 가지고 있다.
다른 시스템 또는 환경에서는 전용 처리기가 하드웨어로 구현되는 저수준의 구성요소이다. 운영체제는 이 처리기들과 통신할 수 없으며 이 처리기들은 독립적으로 자신의 작업을 처리한다.
전용 마이크로프로세서의 사용은 일반적인 형태이며 그렇다고 단일 처리기 시스템을 다중 처리기 시스템으로 변환하지는 않는다. 범용 CPU가 하나 있는 시스템은 단일 처리기 시스템이다.

다중 처리기 시스템(Multi-Processor Systems)

지난 수년 동안 다중 처리기 시스템(병렬 시스템 또는 멀티코어 시스템)이 계산 지형을 지배하기 시작했다. 이러한 시스템은 매우 밀접한 통신을 하는 하나 이상의 처리기들을 가지며, 컴퓨터 버스, 그리고 때로는 클락, 메모리와 주변 장치를 공유한다.
다중 처리기 시스템은 처음에는 서버에 주로 사용되었으나 이후 데스크탑이나 랩탑 시스템으로 이동하였다. 최근에는 스마트폰이나 태블릿 컴퓨터 같은 휴대용 장치에도 등장하고 있다.
다중 처리기 시스템의 장점은 다음과 같다.
1.
증가된 처리량
처리기의 수를 증가시킴으로 우리는 보다 짧은 시간 동안 더욱 많은 일을 수행하기 바라지만 N개의 처리기를 사용할 경우 증가율이 N배가 되지는 않고 N보다 작다.
다수의 처리기가 하나의 태스크를 위해 협력할 경우 모든 부분이 정확히 동작하도록 유지하기 위해 약간의 오버헤드가 유발된다. 이 오버헤드와 공유 자원에 대한 경쟁이 더해져 추가의 처리기에 의해 예상되는 이득을 떨어뜨린다.
2.
규모의 경제
다중 처리기는 여러 개의 단일 시스템에 비해 비용을 절약할 수 있는데, 이는 처리기가 주변 장치, 대용량 저장 장치, 전원 공급 장치를 공유하고 있기 때문이다.
만약 여러 프로그램이 동일한 데이터 집합에 대해 연산을 한다면 하나의 디스크에 이들 데이터를 저장하고 모든 처리기가 이들을 공유하게 하는 것이 여러 컴퓨터가 각자 자신의 로컬 디스크와 많은 데이터의 복사본을 갖는 것보다 비용이 저렴하다.
3.
증가된 신뢰성
만약 기능들이 여러 개의 처리기에 적절히 분산된다면, 한 처리기가 고장 나더라도 시스템이 정지하는 것이 아니라 단지 속도만 느려지게 된다. 만일 우리가 10개의 처리기를 가자ㅣ고 하나가 고정이 나면 나머지 9개의 처리기가 반드시 고장난 처리기의 작업을 대신해야 한다. 따라서 전체 시스템이 완전히 고장 나는 것이 아니라 단지 10% 정도 느리게 수행된다.
컴퓨터 시스템의 증가된 신뢰성은 많은 응용 프로그램에게 필수적이다. 이렇게 살아남은 하드웨어의 수준에 비례해 계속적인 서비스를 제공하는 능력을 우아한 퇴보(graceful degradation)라고 한다.
어떤 시스템은 어느 한 구성요소의 고장에도 불구하고 동작을 계속할 수 있기 때문에 우아한 퇴보를 넘어 결함 허용(fault tolerant)이라고 불린다. 결함 허용 시스템은 오류를 탐지하고, 진단하고 가능하다면 교정할 수 있게 하는 기법이 필요하다는 사실을 주목하라.
HP사의 NonStop 시스템은 오류에도 불구하고 계속적으로 연산할 수 있게 하기 위해 하드웨어와 소프트웨어 모두 복제를 사용하고 있다. 이 시스템은 여러 개의 처리기 쌍으로 구성되고 두 개의 처리기는 맞물려 동작한다.
한 쌍을 구성하는 두 처리기들은 각 명령어를 수행하고 결과를 비교한다. 만일 결과가 다르다면 둘 중 하나의 CPU는 고장난 것으로 간주하고 두 CPU 모두 정치한다. 실행 중이던 프로세스는 다른 CPU 쌍으로 이동하고 실패한 명령어가 재실행된다. 이 해결 방법은 특별한 하드웨어와 상당한 하드웨어 중복이 있기 때문에 비용이 많이 드는 방법이다.
현재 사용되고 있는 다중 처리기 시스템은 두 가지 형태를 가진다. 어떤 시스템은 각 처리기에 특정 태스크가 할당되는 비대칭적 다중 처리(asynmmetric multiprocessing)를 사용한다. 하나의 주 처리기가 시스템을 제어한다.
다른 처리기들은 주 처리기의 명령을 수행하거나 미리 정의된 태스크를 수행한다. 이러한 기법은 주종 관계를 정의한다. 주 처리기는 작업을 스케쥴하고 종속 처리기에 작업을 할당한다.
가장 일반적인 다중 처리기 시스템은 각 처리기가 운영체제 내의 모든 작업을 수행하는 대칭적 다중 처리(symmetric multiprocessing)를 사용한다. 대칭적 다중 처리(SMP)는 모든 처리기가 대등하다는 것을 의미한다. 처리기 간에는 주종 관계가 없다.
그림 1.6은 전형적인 CMP 구조를 보인다. 그림에서 각 처리기가 자신의 레지스터 집합과 사유(또는 로컬)의 캐시를 갖는 것에 유의하라. 그렇지만 모든 처리기는 메모리를 공유한다.
SMP 시스템의 한 예는 UNIX의 상용 버전으로 IBM사가 개발한 AIX가 있다. AIX 시스템은 십여 개의 처리기를 장착하도록 구성될 수 있다. 이 모델의 장점은 중대한 성능 저하를 일으키지 않고 많은 프로세스들이 동시에 수행될 수 있다는 것이다.
대칭적 다중 처리와 비대칭적 다중 처리의 차이점은 하드웨어나 소프트웨어의 결과일 수 있다. 특수한 하드웨어가 다중 처리기들을 차별화 할 수 있으며, 또는 한 개의 주 처리기와 다수의 종 처리기를 허용하도록 소프트웨어를 설계할 수도 있다.
예컨대 동일한 하드웨어 상에서 Sun의 운영체제인 Sun)S 버전 5는 대칭적 다중 처리를 한 반면 버전 4는 비대칭적 다중 처리를 제공한다.
다중처리에서는 계산 능력을 늘리기 위해 CPU를 추가한다. 만일 CPU가 통합된 메모리 제어기를 가졌다면 CPU를 추가하면 시스템에서 주소지정 가능한 메ㅗㅁ리의 양을 늘릴 수 있다.
어떻든 다중처리는 메모리 접근 모델을 균등 메모리 접근(uniform memory access, UMA)에서 비균등 메모리 접근(non-uniform memory access, NUMA)으로 변경하게 만들 수도 있다.
UMA는 임의의 CPU로부터 임의의 RAM을 같은 시간에 접근할 수 있는 상태를 말한다. NUMA의 경우 일부 메모리는 다른 위치의 메모리보다 접근 시간이 오래 걸려 성능 저하를 유발한다.
CPU를 설계하는 최근의 경향은 하나의 칩에 여러 개의 코어(core)를 포함시큰 것이다. 이러한 다중 처리기 시스템은 멀티코어라 불린다. 이들은 단일 코어를 가진 여러 개의 칩보다 효율적이며, 이는 칩 내의 통신이 칩 사이의 통신보다 빠르기 때문이다. 또한 여러 개의 단일 칩보다 전력을 훨씬 덜 소모한다.
멀티코어 시스템은 다중 처리기 시스템인 반면 모든 다중 처리기 시스템이 멀티코어는 아니다.
그림 1.7은 한 칩에 두 개의 코어를 갖는 두 개의 코어 설계를 보인다. 이 설계에서 각 코어는 자신의 레지스터 집합과 자신의 로컬 캐시를 갖는다. 다른 설계에서는 공유 캐시를 갖거나 또는 로컬 및 공유 캐시를 조합하여 사용할 수 있다.
캐시, 메모리 및 버스 경쟁과 같은 구조적 고려를 제외하면 이들 멀티코어 CPU는 운영체제에게는 N개의 표준 처리기로 보인다. 이러한 특성이 운영체제 설계자나 응용 프로그래머에게 이들 코어를 활용하도록 압력을 넣고 있다.
마지막으로 블레이드 서버가 가장 최근에 개발된 형태이며 이 블레이드 서버는 다수의 처리기 보드 및 입출력 보드, 네트워킹 보드들이 하나의 섀시(chassis) 안에 장착되는 형태를 가진다.
블레이드 서버와 전통적인 다중 처리기 시스템과의 차이점은 각 블레이드-처리기 보드는 독립적으로 부팅될 수 있고 자기 자신의 운영체제를 수행한다는 것이다.
어떤 블레이드-서버 보드는 자체가 다중 처리기이기도 하며 이 사실은 컴퓨터 유형 간의 경계를 모호하게 만든다.
근본적으로 블레이드 서버는 여러 독립적인 다중 처리기 시스템으로 구성된다.

클러스터형 시스템(Clustered Systems)

여러 CPU를 가진 시스템의 또 다른 유형은 클러스터형 시스템이다. 클러스터 시스템은 둘 이상의 독자적 시스템 또는 노드들을 연결하여 구성한다는 점에서 다중 처리기 시스템과 차이가 난다. 그러한 시스템은 약결합(loosely coupled)라고 간주된다. 각 노드는 단일 처리기 시스템 또는 멀티코어 시스템일 수 있다.
클러스터링은 통상 높은 가용성(availability)을 제공하기 위해 사용된다. 즉, 클러스터 내 하나 이상의 컴퓨터 시스템이 고장 나더라도 서비스는 계속 제공된다. 일반적으로 고가용성은 시스템에 중복 기능을 추가함으로써 얻어진다.
클러스터 소프트웨어 중 한 층이 클러스터 노드에서 실행된다. 각 노드는 하나 이상의 다른 노드(LAN으로 연결되어 있는)들을 감시한다.
만일 감시 받던 노드가 고장 나면 감시하던 노드가 고장 난 노드의 저장 장치에 대한 소유권을 넘겨 받고 그 노드에서 실행 중이던 응용 프로그램을 다시 시작한다. 사용자와 응용 프로그램의 클라이언트는 잠시 동안의 서비스 중단만을 경험하게 된다.
클러스터링은 비대칭적으로 또는 대칭적으로 구성될 수 있다. 비대칭형 클러스터링에서는 다른 컴퓨터들이 응용 프로그램을 실행하는 동안 한 컴퓨터는 긴급 대기(hot-standby) 모드 상태를 유지한다.
이 긴급 대기 모드의 호스트는 활성 서버들을 감시하는 작업만을 수행한다. 서버가 고장 난다면 긴급 대기 모드의 호스트가 활성 서버가 된다.
대칭형 클러스터링에서는 둘 이상의 호스트들이 응용 프로그램을 실행하고 서로를 감시한다. 가용한 하드웨어를 모두 사용하기 때문에 대칭형 구성이 더 효율적이다. 대칭형 구성이 효율적으로 동작하기 위해서는 하나 이상의 응용 프로그램들이 실행 가능해야 한다.
한 클러스터가 네트워크로 연결된 다수의 컴퓨터 시스템으로 구성되므로 클러스터는 고성능 계산환경을 제공하도록 사용될 수 있다. 이러한 시스템은 클러스터 내의 모든 컴퓨터에서 응용을 병렬 수행할 수 있으므로 단일 처리기나 SMP 시스템보다 훨씬 큰 계산 능력을 제공할 수 있다.
그렇지만 응용이 클러스터를 이용할 수 있도록 작성되어야 한다. 이는 병렬화라는 기법으로 프로그램을 클러스터의 각 컴퓨터에서 수행되는 분리된 요소로 나누는 작업을 포함한다.
전형적으로 이들 응용은 클러스터의 각 계산 노드가 문제의 일부를 해결한 후 모든 노드의 결과가 결합되어 최종 해답을 얻게 된다.
다른 형태의 클러스터로 병렬(parallel) 클러스터와 WAN을 이용한 클러스터링이 있다. 병렬 클러스터는 여러 호스트가 공유 저장 장치 상의 동일한 데이터를 접근할 수 있게 한다.
대부분의 운영체제가 여러 호스트에 의한 이러한 동시 접근을 지원하지 않으므로 병렬 클러스터는 특수 소프트웨어 버전과 특별히 발매된 응용에 의해 달성된다.
예컨대 Oracle Real Application CLuster는 병렬 클러스터에서 수행하도록 설계된 Oracle의 데이터베이스 버전이다. 각 기계는 Oracle을 수행하고 하나의 소프트웨어 층이 공유 디스크에 대한 접근을 관리한다. 각 기계는 데이터베이스 내의 모든 데이터에 대한 완전한 접ㄱ느을 갖는다.
데이터에 대한 공유 접근을 제공하기 위해 시스템은 접근 간의 충돌이 발생하지 않는 것을 보장하기 위해 접근 제어와 잠금 기법을 제공해야 한다. 분산 잠금 관리자(DLM, distributed lock manager)라고 불리는 이 기능은 몇몇의 클러스터 기술에 포함되어 있다.
클러스터 기술은 급변하고 있다. 어떤 클러스터 제품은 수 킬로미터 떨어진 클러스터 노드들 뿐만 아니라 한 클러스터 안에서 수십 개의 노드들을 지원한다. 이러한 개선은 스토리지 에리어 네트워크(SAN, Storage-Area Network)에 의해 가능해졌다.
SAN은 여러 호스트를 여러 스토리지 장치에 부착할 수 있게 한다. 만일 응용과 데이터가 SAN에 저장된다면 클러스터 소프트웨어는 SAN에 연결된 임의의 호스트에서 수행되도록 응용을 배정할 수 있다. 호스트가 고장 나면 다른 호스트가 그 응용을 넘겨 받는다.
데이터베이스 클러스터에서는 수십 개의 호스트가 동일한 데이터베이스를 공유할 수 있기 때문에 성능과 신뢰도를 크게 증가시키게 된다. 그림 1.8은 클러스터 시스템의 일반 구조이다.

운영체제의 구조

운영체제의 가장 중요한 면은 다중 프로그램(multiprogram)을 할 수 있는 능력이다. 일반적으로 단일 사용자는 CPU 또는 입출력 장치를 항상 바쁘게 유지할 수 없다. 다중 프로그램은 CPU가 수행할 작업(코드와 데이터)을 항상 하나 가지도록 작업을 구성함으로써 CPU 이용률을 증가시킨다.
기본 아이디어는 다음과 같다. 운영체제는 한 번에 여러 작업을 메모리에 적재한다(그림 1.9). 이들 작업은 처음에는 디스크의 작업 풀(pool) 내에 유지된다.
왜냐하면 메모리 내에 동시에 저장할 수 있는 작업의 수는 통상 작업 풀에 둘 수 있는 작업의 수보다 훨씬 적기 때문이다. 작업 풀은 디스크 내의 모든 프로세스로 구서오디며 이들은 주 메모리의 할당을 기다린다.
메모리 내의 작업 집합은 작업 풀 내의 작업들의 부분 집합이다. 운영체제는 메모리 내에 있는 작업 중에서 하나를 선택해 실행을 시작한다. 결국 이 작업은 입출력의 종료를 기다리는 등과 같은 어떤 일을 기다려야 하게 된다.
비다중 프로그래밍(non-multiprogrammed) 시스템에서는 CPU가 쉬게 된다. 다중 프로그래밍 시스템에서는 운영체제가 단순히 달느 작업으로 전환해 그 작업을 수행한다.
이 나중의 작업이 어떤 일을 기다려야 한다면, CPU는 또 다른 작업으로 전환된다. 결국 첫 번째 작업이 기다리기를 끝내고 CPU를 다시 차지하게 된다. 따라서 수행될 작업이 최소한 하나 있는 한 CPU는 쉬지 않는다.
이것은 일상생활에서도 흔히 볼 수 있다. 변호사는 한 번에 한 사람의 의뢰인만 상대하는 것이 아니라 재판을 기다리거나 문서 작성을 기다리는 동안 다른 사건을 처리할 수 있다. 변호사가 충분히 많은 의뢰인을 확보하고 있다면 변호사가 일이 없어서 쉬는 일은 발생하지 않는다.
다중 프로그래밍 시스템은 여러 가지 시스템 자원(예컨대 CPU, 메모리, 주변 장치)을 효율적으로 이용할 수 있는 환경을 제공하지만, 사용자를 위해 컴퓨터 시스템과 상호 작용은 제공하지 않는다.
시분할(또는 멀티태스킹: multi-tasking)은 다중 프로그래밍의 논리적 확장이다. 시분할 시스템에서는 CPU가 다수의 작업들을 교대로 수행하지만 매우 빈번하게 교대가 일어나기 때문에 프로그램이 실행되는 동안 사용자들은 각자 자기의 프로그램과 상호 작용 할 수 있다.
시분할 시스템은 사용자와 시스템 간에 직접적인 통신을 제공하는 대화식(interactive) 컴퓨터 시스템을 필요로 한다.
사용자는 키보드, 마우스 터치 패드 같은 입력 장치를 이용하여 운영체제나 프로그램에 직접 명령하고 출력 장치의 즉각적인 응답을 기다린다. 따라서 응답 시간(response time)이 짧아야 하며 전형적으로 1초 정도 이내이다.
시분할 운영체제는 동시에 많은 사용자가 컴퓨터를 공유하도록 한다. 시분할 시스템에서 각각의 동작이나 명령은 대체로 짧은 경향이 있기 때문에 각 사용자는 단지 짧은 시간 동안만 CPU 시간이 필요하다.
시스템이 한 사용자에서 다음 사용자로 빠르게 전환되기 때문에 각 사용자는 자신이 전체 컴퓨터를 전용하는 것처럼 느끼지만 실제로는 다수의 사용자가 하나의 컴퓨터를 공유한다.
시분할 운영체제는 각 사용자에게 시분할 되는 컴퓨터의 작은 부분을 제공하기 위해 CPU 스케쥴링과 다중 프로그래밍을 사용한다. 각 사용자는 메모리에 최소한 하나의 독립된 프로그램을 가지고 있다.
메모리에 적재되어 있고 실행되고 있는 프로그램을 일반적으로 프로세스라고 한다. 프로세스가 수행될 때는 전형적으로 자신이 종료되거나 입출력을 수행할 필요가 있을 때까지 아주 짧은 시간 동안만 실행된다.
시분할과 다중 프로그래밍 운영체제에서는 여러 작업이 메모리에 동시에 유지되어야 한다. 만약 몇몇 작업이 메모리로 옮겨올 준비가 되었고 그들 전부를 메모리에 보관할만한 공간이 불충분하다면 시스템은 그들 중 몇 개를 선택해야 한다. 이러한 결정을 하는 것이 작업 스케줄링이다.
운영체제가 작업 풀에서 하나의 작업을 선택하면 실행을 위해 그 작업을 메모리에 적재한다. 메모리에 여러 개의 프로그램이 동시에 있을 경우에 어떤 형태의 메모리 관리가 필요한데 이것은 8, 9장에서 다룬다.
또 여러 개의 작업이 동시에 실행 준비가 되어 있으면 시스템은 그들 중 하나를 선택해야 한다. 이러한 결정을 내리는 것을 CPU 스케줄링이라한다.
마지막으로 병행적으로 수행되는 다수의 작업은 프로세스 스케줄링, 디스크 저장 장치 그리고 메모리 관리를 포함하여 운영체제 모든 단계에서 상호간에 영향을 미치는 능력이 제한될 필요가 있다.
시분할 시스템에서 운영체제는 적절한 응답 시간을 보장해야 한다. 이는 종종 스와핑에 의해 달성되는데, 스와핑은 프로세스를 주 메모리에서 디스크로 적절하게 스왑인(swap-in) 또는 스왑아웃(swap-out) 시킨다.
합리적인 응답시간을 보장하는 더 일반적인 방법은 가상 메모리(virtual memory)인데 이것은 일부만 메모리에 있는 작업의 수행을 허용하는 기법이다.
이 기법의 주요한 이점은 프로그램이 물리 메모리의 크기보다 더 커도 된다는 것이다. 더욱이 가상 메모리는 주 메모리를 크고 균등한 저장 장치의 배열로 추상화하여 사용자에게 보이는 논리 메모리를 물리 메모리로부터 분리시킨다. 이러한 기법은 프로그래머를 메모리 저장 장치의 한계로부터 자유롭게 해준다.
시분할 시스템은 반드시 파일 시스템도 제공해야 한다. 파일 시스템은 다수의 디스크 상에 존재하므로 디스크 관리 기법이 반드시 제공되어야 한다. 또한 시분할 시스템은 부적당한 사용으로부터 자원을 보호하기 위한 기법을 제공해야 한다.
작업이 질서 정연하게 실행되도록 하기 위해 시스템은 반드시 작업 동기화와 통신 기법을 제공해야 하며, 작업이 서로를 영원히 기다리는 교착 상태(deadlock)에 빠지지 않도록 해야 한다.

운영체제 연산

앞서 언급한 것처럼 현대의 운영체제는 인터럽트 구동식(interrupt driven)이다. 실행할 프로세스가 없고, 서비스할 입출력 장치도 없고 응답해 주어야 할 사용자도 없다면 운영체제는 무언가 일어나기를 기다리며 조용히 앉아 있을 것이다.
사건은 거의 항상 인터럽트나 트랩을 발생시켜 신호를 보낸다. 트랩(또는 예외)는 오류, 혹은 사용자 프로그램의 운영체제 서비스 수행 요청에 의해 유발되는 소프트웨어에 의해 생성된 인터럽트이다.
운영체제의 인터럽트 구동식 특성은 시스템의 일반적 구조를 정의한다. 각 타입의 인터럽트에 대해 어떠한 행동을 취해야 하할지는 운영체제 내의 서로 다른 코드 세그먼트가 결정한다. 한 인터럽트를 처리하기 위해 하나의 인터럽트 서비스 루틴이 제공된다.
운영체제와 사용자는 컴퓨터 시스템의 하드웨어와 소프트웨어 자원을 공유하기 때문에 사용자 프로그램의 오류가 현재 수행 중인 프로그램에만 문제를 일으키도록 보장해야 한다. 공유 때문에 한 프로그램의 버그로 인해 많은 프로그램들이 악영향을 받을 수 있다.
예컨대 만일 하나의 프로세스가 무한 루프에 빠지면 다른 프로세스의 정상적인 동작을 방해할 수 있다. 다중 프로그래밍 환경에서는 좀 더 미묘한 오류가 발생할 수 있다. 하나의 잘못된 프로그램이 다른 프로그램 코드나 데이터 또는 운영체제 자체를 변경할 수 있다.
이러한 종류의 오류에 대한 보호 기능이 없으면 컴퓨터 시스템은 한 순간에 단 하나의 프로세스만을 수행시키거나 또는 모든 출력 결과를 의심할 수 밖에 없다. 올바르게 설계된 운영체제는 잘못된 또는 악의적인 프로그램이 다른 프로그램이 부정확하게 수행되지 않도록 보장해야 한다.

이중 연산 모드

운영체제의 적절한 동작을 보장하기 위해 운영체제 코드의 실행과 사용자 정의 코드의 실행을 구분할 수 있어야 한다. 많은 운영체제에 의해 취해지는 접근 방법은 우리가 여러 실행 모드를 구분할 수 있도록 하드웨어 지원을 제공하는 것이다.
적어도 두 개의 독립된 연산 모드, 즉 사용자 모드와 커널 모드(수퍼바이저 모드, 시스템 모드 혹은 특권 모드)를 필요로 한다.
모드 비트(mode bit)라고 하는 하나의 비트가 현재의 모드를 나타내기 위해 컴퓨터의 하드웨어에 추가되었다. 이 비트는 커널 모드(0) 또는 사용자 모드(1)을 나타낸다.
모드 비트의 사용으로 우리는 운영체제를 위해 실행되는 작업과 사용자를 위해 실행되는 작업을 구분할 수 있다. 컴퓨터 시스템이 사용자 응용을 위하여 실행될 때 시스템은 사용자 모드에 있게 된다. 그러나 사용자 응용이 운영체제로부터 서비스를 요청하면(시스템 호출을 통함) 이 요청을 수행하기 위해서는 사용자 모드에서 커널 모드로 전환해야 한다. 이 절차가 그림 1.10에 나와 있다.
시스템 부트 시 하드웨어는 커널 모드에서 시작한다. 이어 운영체제가 적재되고 사용자 모드에서 사용자 프로세스가 시작된다. 트랩이나 인터럽트가 발생할 때마다 하드웨어는 사용자 모드에서 커널 모드로 전환한다(즉 모드 비트를 0으로 변경). 시스템은 사용자 프로그램으로 제어를 넘기기 전에 항상 사용자 모드(모드 비트를 1로 설정)로 전환한다.
동작의 이중 모드는 잘못된 사용자로부터 운영체제를, 그리고 잘못된 사용자 서로를 보호하는 방법을 제공한다. 우리는 악영향을 끼칠 수 있는 일부 명령을 특권 명령(privileged instruction)으로 지정함으로써 이러한 보호를 달성한다.
하드웨어는 특권 명령이 커널 모드에서만 수행되도록 허용한다. 사용자 모드에서 특권 명령을 수행하려고 시도하면 하드웨어는 이를 실행하지 않고, 불법적인 명령으로 간주해 운영체제로 트랩을 건다.
커널 모드로 전환하는 명령어가 특권 명령의 한 예다. 또 다른 예는 입출력 제어, 타이머 관리, 그리고 인터럽트 관리를 위한 명령어들이 있다.
모드 개념은 두 개의 모드 이상으로 확장될 수 있다(이 경우 CPU는 모드를 설정하고 검사하기 위해 한 비트 이상을 사용해야 한다). 가상화를 지원하는 CPU는 시스템을 가상 기계 관리자(virtual machine manager, VMM) —따라서 가상화 관리 소프트웨어—가 제어하고 있는지를 나타내기 위해 종종 별도의 모드 비트를 사용한다.
이 모드에서는 VMM이 커널보다는 작지만 사용자 프로세스보다는 큰 권한을 가진다. VMM은 가상 기계를 생성하고 관리하며 CPU 상태 변경을 하기 위해 이러한 수준의 특권을 필요로 한다. 때로는 여러 커널 구성요소들이 다른 모드를 사용하기도 한다.
이제 컴퓨터 시스템의 명령 실행 주기를 살펴보자. 초기 제어는 운영체제에게 있다. 여기서는 명령어가 커널 모드에서 실행된다. 제어가 사용자 응용에게 넘어 가면 모드가 사용자 모드로 지정된다. 결국 제어는 인터럽트, 트랩, 또는 시스템 호출을 통하여 운영체제에게 다시 넘어오게 된다.
시스템 호출은 사용자 프로그램이 자신을 대신하여 운영체제가 수행하도록 지정되어 있는 작업들을 운영체제에게 요청할 수 있는 방법을 제공한다. 시스템 호출은 컴퓨터 시스템의 처리기가 지원하는 기능에 따라 다양한 방법으로 호출된다.
어떤 형태를 가지든 시스템 호출은 운영체제에 의해 수행될 동작을 사용자 프로세스가 요청할 수 있게 한다. 시스템 호출은 일반적으로 인터럽트 벡터의 특정 위치로 트랩을 거는 형태를 취한다.
이 트랩은 보통의 trap 명령어를 통해 수해오디지만 (예컨대 MIPS 같은) 몇몇 시스템은 syscall이라는 특정 명령어를 가지기도 한다.
시스템 호출이 수행될 떄 시스템 호출은 하드웨어에 의해 하나의 소프트웨어 인터럽트로 취급된다. 제어가 인터럽트 벡터를 통해 운영체제 내의 서비스 루틴으로 전달되고, 모드 비트가 커널 모드로 설정된다.
시스템 호출 서비스 루틴은 운영체제의 일부이다. 커널은 인터럽트를 발생시킨 명령을 검사하여 어떤 시스템 호출이 발생했는지를 결정한다.
이때 전달된 인수가 사용자 프로그램이 요청하는 서비스 타입을 표시한다. 요청이 필요로 하는 추가의 정보는 레지스터, 스택 또는 메모리로(이 때는 메모리 위치에 대한 포인터가 레지스터에 전달된다) 전달될 수 있다.
커널은 인수가 정확하고 합법적인지를 검증하고 요청을 수행한 후 제어를 시스템 호출 다음의 명령으로 복귀한다.
하드웨어가 이중 모드를 지원하지 않을 경우 운영체제에 심각한 결점을 초래할 수 있다. 예컨대 MS-DOS는 모드 비트가 없는, 따라서 이중 모드가 없는 Intel 8088을 위해 작성되었다.
그러므로 잘못된 사용자 프로그램이 데이터를 운영체제 부분에 덮어 기록함으로써 운영체제를 지워버릴 수 있고, 또한 여러 프로그램이 동시에 한 장치에 기록될 수 있으며 그 경우 불행한 결과가 발생할 수 있다.
팬티엄과 같은 인텔 PCU의 보다 최근의 버전은 이중 모드를 지원한다. 결과적으로 보다 최근의 운영체네인 Windows 7과 Unix, Linux는 이 이중 모드 기능을 이용하여 운영체제에 더 많은 보호를 제공한다.
하드웨어 보호 기능이 제공되면 모드 규칙을 위반하는 오류가 하드웨어에 의해 탐지된다. 이러한 오류는 일반적으로 운영체제가 처리한다.
사용자 프로그램이 불법적인 명령을 수행하려 하거나 사용자 주소 공간이 아닌 메모리에 접근을 시도하는 등과 같은 오류가 발생하면 하드웨어는 운영체제로 트랩을 발생시킨다. 트랩은 인터럽트처럼 인터럽트 벡터를 통해 제어를 운영체제에 넘긴다.
프로그램 오류가 발생할 때마다 운영체제는 비정상적으로 프로그램을 종료시킨다. 이것은 사용자가 요청한 비정상적인 종료와 동일한 코드에 의해 처리된다. 적절한 오류 메시지가 주어지며, 프로그램의 메모리가 덤프된다.
메모리 덤프는 사용자나 프로그래머가 이를 조사하고 프로그램을 수정하여 다시 실행시킬 수 있도록 통상 파일에 기록된다.

타이머

우리는 운영체제가 CPU에 대한 제어를 유지할 수 있도록 보장해야 한다. 우리는 사용자 프로그램이 무한 루프에 빠지거나 시스템 서비스 호출에 실패하여 제어가 운영체제로 복귀하지 않는 경우가 없도록 반드시 방지해야 한다. 이러한 목적을 달성하기 위해 타이머(timer)를 사용할 수 있다.
타이머는 지정된 시간 후 컴퓨터를 인터럽트 하도록 설정할 수 있다. 이 시간은 고정(예컨대 1/60초), 혹은 가변(예컨대 1밀리초에서 1초까지)일 수 있다.
가변 타이머는 일반적으로 고정률의 클락(fixed-rate clock)과 계수기로 구현한다. 운영체제는 계수기 값을 설정한다. 클락이 똑딱(tick)할 때마다 계수기가 감소한다. 계수기가 0이될 때 인터럽트가 발생한다.
예컨대 1밀리초 클락의 10비트 계수기는 1밀리초 단위로 1밀리초에서 1024밀리초 사이의 간격을 갖는 인터럽트를 허용한다.
사용자에게 제어를 양도하기 전에 운영체제는 타이머가 인터럽트를 할 수 있도록 설정되었는지를 확인한다. 만약 타이머가 인터럽트를 발생하면, 제어는 자동적으로 운영체제에 넘어가며, 운영체제는 인터럽트를 치명적인 오류로 취급하거나 또는 프로그램에게 더 많은 시간을 줄 수 있다. 타이머의 값을 변경하는 명령은 명백히 특권 명령이다.
따라서 사용자 프로그램이 너무 오래 실행되는 것을 방지하기 위해 타이머를 사용할 수 있다. 가장 간단한 방법은 계수기를 프로그램이 실행되도록 허용된 시간으로 초기화하는 것이다.
예컨대 7분의 시간 제한을 가진 프로그램은 계수기를 420으로 초기화한다. 초마다 타이머가 인터럽트하고 계수기를 1씩 감소시키다가 음수가 되면 운영체제는 할당된 제한 시간을 초과한 그 프로그램을 종료한다.

프로세스 관리

프로그램은 그 명령이 CPU에 의해 수행되지 않으면 아무 일도 할 수 없다. 언급한 것처럼 실행 중인 프로그램이 프로세스이다. 컴파일러와 같은 하나의 시분할 사용자 프로그램은 하나의 프로세스가 된다.
PC 상에서 한 개인 사용자에게 의해 수행되고 있는 워드 프로세싱 프로그램이나, 출력을 프린트로 보내는 시스템 태스크도 하나의 프로세스가 된다.
프로세스는 자신의 일을 수행하기 위해 CPU 시간, 메모리, 파일 그리고 입출력 장치를 포함한 여러 자원을 필요로 한다. 이러한 자원은 프로세스가 생성될 때 획득하는 여러 물리적, 논리적 자원 외에 여러 초기화 데이터도 전달될 수 있다.
우리는 프로그램 그 자체는 프로세스가 아님을 강조한다. 즉 하나의 프로그램은 디스크에 저장된 파일의 내용과 같이 수동적(passive) 개체인 반면, 프로세스는 다음 수행할 명령을 지정하는 프로그램 카운터(program counter)를 가진 능동적(active) 개체이다.
한 프로세스의 수행은 반드시 순차적이라야 한다. CPU는 그 프로세스가 끝날 때까지 그 프로세스의 명령들을 차례대로 수행한다. 게다가 어느 한 순간에는 많아야 그 프로세스를 위해 하나의 명령만 수행된다.
따라서 두 개의 프로세스가 동일한 프로그램과 연관되어 있더라도 그들은 두 개의 별도의 수행 순서로 간주된다. 다중 스레드 프로세스는 복수개의 프로그램 카운터를 가지고 있으며 이 카운터들은 각 스레드가 실행할 다음 명령어를 가리키게 된다.
한 프로세스는 한 시스템 내의 작업의 단위이다. 이러한 시스템은 프로세스의 집합으로 구성되는데 프로세스들 중 일부는 운영체제 프로세스들(시스템 코드를 수행하는 프로세스들)이며 나머지는 사용자 프로세스들(사용자 코드를 수행하는 프로세스들)이다.
이들 모든 프로세스는 그들 간에 하나의 CPU를 멀티플렉싱(multiplexing) 함으로써 병행 수행될 수 있다.
운영체제는 프로세스 관리와 연관해 다음과 같은 활동에 대한 책임으 ㄹ진다.
CPU에 프로세스와 스레드를 스케쥴하기
사용자 프로세스와 시스템 프로세스의 생성과 제거
프로세스의 일시 중지와 재수행
프로세스 동기화를 위한 기법 제공
프로세스 통신을 위한 기법 제공

메모리 관리

주 메모리는 현대 컴퓨터 시스템의 작동에 중추적인 역할을 한다. 메모리는 크기가 수십 만에서 수십 억까지의 범위를 갖는 바이트의 대용량 배열이다. 각 바이트는 자신의 주소를 가진다.
주 메모리는 CPU와 입출력 장치에 의해 공유되는 빠른 접근이 가능한 데이터의 저장소이다. 폰 노이만 방식의 컴퓨터에서는 중앙 처리기가 명령어 인출 주기(instruction fetch-cycle) 동안 주 메모리로부터 명령어를 읽고, 자료 인출 주기(data fetch-cycle) 동안 주 메모리로부터 데이터를 읽고 또한 쓴다.
주 메모리는 일반적으로 CPU가 직접 주소를 지정할 수 있고 그리고 직접 접근할 수 있는 유일한 대량 메모리이다. 예컨대 CPU가 디스크에서 가져온 데이터를 처리하려면 이들 데이터는 먼저 주 메모리로 전송되어야 한다.
프로그램이 수행되기 위해서는 반드시 절대 주소로 매핑(mapping)되고 메모리에 적재되어야 한다. 프로그램을 수행하면서 이러한 절대 주소를 생성하여 메모리의 프로그램 명령어와 데이터에 접근한다.
결국 프로그램이 종료되고 프로그램이 차지하던 메모리 공간은 가용공간으로 선언되고 다음 프로그램이 적재되어 수행될 수 있다.
CPU 이용률과 사용자에 대한 컴퓨터의 응답 속도를 개선하기 위해 우리는 메모리에 여러 개의 프로그램을 유지해야 하며 이를 위해 메모리 관리 기법이 필요하다.
이러한 메모리 관리 기법에는 여러 종류가 있다. 이러한 기법은 메모리 관리에 대한 여러 접근 방법을 반영하는데, 각 알고리즘의 효율성은 특정 상황에 따라 다르다.
특정 시스템에 대한 메모리 관리 기법의 선택은 여러 요인에 의해 결정되지만 특히 시스템의 하드웨어 설계에 좌우된다. 각 알고리즘은 자신의 하드웨어 지원을 필요로 한다.
운영체제는 메모리 관리와 관련하여 다음과 같은 일을 담당해야 한다.
메모리의 어느 부분이 현재 사용되고 있으며 누구에 의해 사용되고 있는지를 추적해야 한다.
어떤 프로세스(또는 그 일부)들을 메모리에 적재하고 제거할 것인가를 결정해야 한다.
필요에 따라 메모리 공간을 할당하고 회수해야 한다.

저장장치 관리

컴퓨터 시스템의 편리한 사용을 위해 운영체제는 정보 저장 장치에 대한 균등한 논리적 관점을 제공한다. 운영체제는 저장 장치의 물리적 특성을 추상화하여 논리적인 저장 단위인 파일을 정의한다. 운영체제는 파일을 물리적 매체로 맵하며 저장 장치를 통해 이들 파일에 접근한다.

파일 시스템 관리

파일 관리는 가장 눈에 띄는 운영체제 구성 요소 중의 하나이다. 컴퓨터는 여러 타입의 물리적 매체에 정보를 저장할 수 있다. 자기 디스크, 광 디스크, 자기 테이프 등은 자신의 특성과 물리적 구성을 가지고 있다.
각 매체는 디스크 드라이브 혹은 테이프 드라이브와 같은 장치에 의해 제어되며, 이들 장치 또한 자신의 독특한 특성을 가지고 있다. 이러한 속성에는 접근 속도, 용량, 데이터 전송률, 접근 방식(순차 혹은 임의) 등이 있다.
파일은 파일 생성자에 의해 정의된 관련 정보의 집합체이다. 일반적으로 파일은 프로그램(소스와 목적 프로그램 형태)과 데이터를 나타낸다.
데이터 파일은 숫자, 영문자, 영숫자 등으로 구성되며, 파일은 텍스트 파일과 같은 자유 형태일 수도 있고, 엄격하게 포맷된 형태일 수도 있다. 명백히 파일의 개념은 지극히 일반적이다.
운영체제는 테이프와 디스크 같은 대량 저장 매체와 그것을 제어하는 장치를 관리함으로써 파일의 추상적인 개념을 구현한다. 또한 파일은 사용을 쉽게 하기 위해 통상 디렉토리들로 구성된다.
마지막으로 다수의 사용자가 파일에 접근하려고 할 때는 누구에 의해 어떤 방법으로 파일이 접근되어야 하는가를 통제하는 것이 바람직하다.
운영체제는 파일 관리를 위해 다음과 같은 일을 담당한다.
파일의 생성 및 제거
디렉토리 생성 및 제거
파일과 디렉토리를 조작하기 위한 프리미티브의 제공
파일을 보조 저장 장치로 매핑
안정적인(비휘발성) 저장 매체에 파일을 백업

대용량 저장장치 관리

주 메모리는 모든 데이터와 프로그램을 수용하기에 용량이 작고 전원이 꺼지면 저장된 데이터가 사라지기 때문에 컴퓨터 시스템은 반드시 주 메모리 내용을 저장하기 위해 보조 저장 장치를 제공해야 한다.
대부분의 현대 컴퓨터 시스템은 디스크를 프로그램과 데이터를 위한 주된 온라인 저장 매체로 사용하고 있다.
대부분의 프로그램은 주 메모리에 적재될 때까지 디스크에 저장되어 있고, 그들의 처리의 출발지와 목적지로서 디스크를 사용하고 있다.
운영체제는 디스크 관리를 위하여 다음과 같은 기능을 담당한다.
자유 공간의 관리
저장 장소 할당
디스크 스케쥴링
(이하 생략)

캐싱(caching)

캐싱은 컴퓨터 시스템의 중요한 원리이다. 정보는 통상 어떤 저장 장치(주 메모리 같은)에 보관된다. 정보가 사용됨에 따라 보다 빠른 장치인 캐시에 일시적으로 복사된다. 그러므로 우리가 특정 정보가 필요할 경우, 우리는 먼저 캐시에 그 정보가 있는지를 조사해 봐야 한다.
만약 캐시에 있으면 우리는 그 정보를 캐시로부터 직접 사용하지만, 만일 캐시에 없다면 주 메모리 시스템으로부터 가져와야 하며, 이 때 이 정보가 다음에 곧 다시 사용될 확률이 높다는 가정 하에 캐시에 넣는다.
이에 덧붙여 인덱스 레지스터와 같은 CPU 내부의 프로그램 가능한 레지스터들은 주 메모리를 위한 고속의 캐시로 볼 수 있다. 프로그래머(또는 컴파일러)는 어느 정보를 주 메모리에 두고 어느 정보를 레지스터에 둘 것인지를 결정하는 레지스터 할당 정책과 교체 알고리즘을 구현한다.
전적으로 하드웨어로 구현된 캐시도 있다. 예컨대 대부분의 시스템은 다음에 수행될 것으로 예상되는 명령을 넣어 두는 명령 캐시를 갖고 있다. 만약 명령 캐시가 없다면 CPU는 주 메모리로부터 다음 열영을 인출해 올 동안 몇 사이클을 기다려야 한다.
캐시의 크기에 한계가 있기 때문에 캐시 관리가 설계의 중요한 문제가 된다. 캐시의 크기와 교체 정책을 잘 선택하면 모든 접근의 80-99%를 캐시에서 얻을 수 있어 극도로 높은 성능을 얻게 된다.
저장 장치의 계층구조에서 각 수준간의 정보 이동은 하드웨어 설계나 제어하는 운영체제에 따라 명싲거 또는 묵시적으로 이루어진다. 예컨대 캐시로부터 CPU 및 레지스터로의 데이터 전송은 통상 운영체제의 간섭 없이 하드웨어적으로 이루어진다. 반면 디스크와 메모리 간의 데이터 전송은 통상 운영체제에 의해 제어된다.
메모리 계층 구조에서 동일한 데이터가 서로 다른 수준의 저장 장치 시스템에 나타나게 된다.
예컨대 B라는 파일에 있는 A라는 변수가 1 증가 되어야 한다고 생각해 보자. 파일 B가 자기 디스크에 있다고 가정해 보자. 증가 연산은 먼저 A가 있는 디스크 블록을 주 메모리로 복사해오는 입출력 연산을 호출함으로써 진행된다.
이어서 A를 캐시에 복사하고, 이어 A를 다시 내부 레지스터로 복사한다. 따라서 A의 복사본이 여러 곳에 존재하게 된다. (그림 1.12) 내부 레지스터에서 증가가 일어나면 A의 값은 여러 저장 장치 시스템에서 서로 달라진다. A의 값은 자기 디스크에 새로운 A의 값이 다시 기록된 후에야 비로소 동일해 진다.
어떤 시간에 단지 하나의 프로세스만 실행하는 환경에서는 이러한 기법이 아무런 문제가 없다. 정수 A에 대한 접근은 항상 계층 구조 최상위 값을 참조하기 때문이다.
그러나 CPU가 여러 개의 프로세스들 사이에서 이러지리 전환되는 멀티태스킹 환경에서는 여러 개의 프로세스가 A에 접근하기를 원할 경우 이들 각 프로세스가 가장 최근에 갱신된 A의 값을 얻을 것을 보장하기위해서는 극도의 조심이 필요하다.
CPU가 내부 레지스터를 유지할 뿐만 아니라 로컬 캐시(그림 1.6)도 갖고 있는 다중 처리 환경 하에서는 상황이 더 복잡해진다. 이런 환경에서는 A의 복사본이 동시에 여러 캐시에 존재할 수 있다.
여러 개의 CPU가 모두 동시에 실행될 수 있으므로 한 캐시에 있는 A의 값이 갱신될 경우 그것은 A가 존재하는 모든 캐시에 즉각적으로 반영되어야 한다. 이러한 상황을 캐시 일관성 문제라고 하며, 이는 일반적으로 (운영체제보다 아래 수준에서 처리되는) 하드웨어적 문제이다.
분산 환경에서는 문제가 더욱 더 복잡해진다. 분산 환경에서는 동일한 파일의 다수의 복사본이 공간적으로 분산된 여러 컴퓨터에 유지될 수 있다. 여러 개의 복사본이 병렬로 접근되고 갱신될 수 잇으므로 우리는 한 장소에서 한 복사본이 갱신될 경우 가능한 한 빨리 모든 복사본이 갱신될 것을 보장해야 한다.

입출력 시스템(I/O Systems)

운영체제의 목적 중 하나는 사용자에게 특정 하드웨어 장치의 특성을 숨기는 것이다. 예컨대 UNIX에서 입출력 장치의 특성은 입출력 서브시스템에 의해 운영체제 자체의 대부분으로부터 숨겨져 있다.
입출력 시스템은 다음과 같이 구성되어 있다.
버퍼링, 캐싱, 스풀링을 포함한 메모리 관리 구성 요소
일반적인 장치 드라이버 인터페이스
특정 하드웨어 장치들을 위한 드라이버
단지 장치 드라이버만이 자신에게 지정된 특정 장치의 특성을 알고 있다.

보호와 보안(Protection and Security)

만일 컴퓨터 시스템이 다수의 사용자를 가지며, 다수의 프로세스의 병렬 수행을 허용한다면 데이터에 대한 접근은 반드시 규제되어야 한다. 이를 위해 파일, 메모리 세그먼트, CPU 및 다른 자원들에 대해 운영체제로부터 적절한 허가를 획득한 프로세스만이 작업할 수 있도록 보장하는 기법이 필요하다.
예컨대 메모리 주소 지정 하드웨어는 프로세스가 자신의 주소 영역에서만 실행될 수 있도록 보장한다. 타이머는 프로세스가 CPU의 제어를 얻은 후 결국에는 제어를 양도하도록 보장한다.
여러 주변 장치의 무결성이 보호받도록 장치 제어 레지스터들에 사용자가 접근할 수 없게 한다.
보호(protection)란 컴퓨터 시스템이 정의한 자원에 대해 프로그램, 프로세스, 또는 사용자들의 접근을 제어한느 기법이다. 이 기법은 시행될 제어에 대한 명세와 이들을 강제 시행하기 위한 방법을 규정하는 수단을 반드시 제공해야 한다.
보호는 구성 요소 서브시스템 간의 인터페이스에서 잠재적인 오류를 검출함으로써 시스템의 신뢰성을 증가시킬 수 있다. 인터페이스 오류를 초기에 발견하면 종종 고장난 서브시스템에 의해 정상적인 서브시스템이 오염되는 것을 방지할 수 있다. 보호되지 않는 자원은 권한이 없거나 또는 무자격 사용자에 의해 사용 되는 것을 방지할 수 있다.
컴퓨터 시스템은 충분한 보호 기능을 가지고 있더라도 여전히 고장이 나거나 부적절한 접근을 허용할 수 있다. 사용자의 인증 정보가 도난 당했다고 가정 하자. 파일과 메모리 보호 기능이 작동하더라도 사용자의 데이터는 복사 또는 삭제 될 수 있다. 이러한 외부 또는 내부의 공격을 방어하는 것이 바로 보안 기능이다.
이러한 공격은 시스템의 많은 범우에 대해 가능하고 바이러스, 웜, 서비스 거부 공격, 식별자 도용, 서비스 도용 등이 있다. 어떤 운영체제는 이 공격들의 일부를 막는 기능을 고려하고 있으며 다른 운영체제들은 이를 정책이나 부가적인 응용에 맡기고 있다.
보호와 보안을 제공하기 위해서는 시스템의 모든 사용자들을 구분할 수 있어야 한다. 대부분의 운영체제들은 사용자 이름과 연관된 사용자 식별자(user IDs)의 리스트를 유지한다. Windows 용어로는 보안 식별자(SID, security ID)라고 한다.
이 식별자는 사용자마다 할당되고 시스템에서 유일한 값을 가진다. 사용자가 로그인 할 때 인증 단계에서 사용자에 맞는 적절한 식별자를 결정한다. 이 사용자 식별자는 사용자의 모든 프로세스나 스레드에 연관된다.
어떤 상황에서는 각 사용자가 아니라 사용자의 집합을 구분하기를 원한다. 예컨대 UNIX 시스템에서는 파일의 소유주에게는 모든 연산을 허용하고 일부 사용자들에게는 읽기만 허용할 수도 있다.
시스템을 정상적으로 사용하는 동안 사용자의 식별자외 그룹 식별자만 있으면 충분하다. 그러나 사용자는 떄때로 원하는 작업을 수행하기 위해 권한을 상승해야 할 때가 있다. 예컨대 사용자가 제한된 장치를 접근해야 할 때도 있다.
운영체제는 권한 상승을 허용하는 다양한 방법을 제공하는데 예컨대 UNIX에서는 프로그램이 수행될 때 setuid 속성을 이용하여 현 사용자의 식별자가 아니라 접근하려고 하는 파일의 소유주 식별자를 이용하여 동작할 수 있다. 프로세스는 종료되거나 특권을 해제하기 전까지 이 유효 사용자 식별자(effective user ID)를 이용하여 수행된다.

커널 자료 구조

리스트, 스택 및 큐

배열은 각 원소가 직접 접근될 수 있는 가장 단순한 자료 구조이다. 예컨대 주 메모리는 하나의 배열로 구축된다.
배열에 이어 리스트가 컴퓨터 과학에서 가장 기본적인 자료 구조일 것이다. 배열의 각 항은 직접 접근할 수 있으나 리스트의 항들은 특정 순서로 접근해야 한다. 즉 리스트는 데이터 값들의 집단을 하나의 시퀀스로 표시한다. 이 구조를 구현하는 가장 일반적인 방법이 연결 리스트(linked list)이다.
단일 연결 리스트에서는 각 항은 그림 1.13와 같이 후속 항을 가리킨다.
이중 연결 리스트에서는 한 항은 그림 1.14와 같이 자신의 앞 항이나 뒤 항을 가리킨다.
원형 연결 리스트에서는 그림 1.15와 같이 리스트의 마지막 항이 널(null)이 아니라 첫 항을 가리킨다.
스택은 순차적 순서를 가진 자료구조로 항을 넣거나 꺼내는데 후입선출(last in first out, LIFO)을 사용한다.
큐는 순차 순서의 자료구조로 선입선출(first in first out, FIFO)을 사용한다.

트리

트리는 데이터의 서열을 표시하는데 사용 가능한 자료 구조이다. 트리 구조에서 데이터 값들은 부모-자식 관계에 의해 연결된다. 일반 트리(general tree)에서 부모는 임의의 수의 자식을 가질 수 있다.
이진 트리에서 부모는 최대 두 개의 자식을 가질 수 있으며, 이들은 좌측 자식, 우측 자식이라 부른다.
이진 탐색 트리는 추가로 부모의 두 자식 사이에 좌측 자식 ≤ 우측 자식의 순서를 요구한다. 그림 1.16은 이진 탐색 트리의 예를 보인다.
이진 탐색 트리에서 한 항을 찾을 때 최악의 경우 성능이 O(n)이 나올 수 있는데, 이러한 상황을 방지하기 위해 우리는 균형 이진 탐색 트리라는 알고리즘을 사용할 수 있다. 최악의 경우 성능 O(log n)을 보장한다. Linux가 CPU 스케줄링 알고리즘의 일부로 균형 이진 탐색 트리를 사용한다.

해시 함수와 맵

해시 함수는 데이터를 입력으로 받아 이 데이터에 산술 연산을 수행하여 하나의 수를 복귀한다. 이 수는 그 데이터를 인출하기 위해 테이블의 인덱스로 사용할 수 있다.
해시함수의 어려운 점은 두 개의 입력이 하나의 출력 값을 가질 수 있다는 것인데, 이를 해시 충돌(hash collision)이라 한다. 테이블의 각 항에 연결 리스트를 두어 동일한 해시 값을 갖는 모든 항을 수록하게 한다.
해시 함수의 한 용도는 해시 맵을 구현하는 일이다. 해시 맵은 해시 함수를 사용하여 [키:값]을 연관 시킨다.
예컨대 operating이란 키를 system이란 값으로 맵할 수 있다. 일단 매핑이 성립되면 해시 함수를 적용하여 해시 맵으로부터 그 값을 얻을 수 있다. (그림 1.17)

비트맵

비트맵은 n개의 항의 상태를 나타내는데 사용 가능한 n개의 이진 비트의 스트링이다. 예컨대 다수의 자원이 있다 하자. 각 자원의 가용 여부를 이진 비트의 값으로 표시한다. 0은 자원이 사용 가능함을 표시하고, 1은 사용 불가능함을 표시한다. 비트맵에서 i번째 위치의 값은 i번째 자원과 연관되어 있다.
예컨대 아래의 비트맵을 고려해 보자. 자원 2, 4, 5, 6, 8은 사용가능하지 않다.
001011101
비트맵의 힘은 이들의 공간 효율을 생각하면 자명하다. 우리는 단일 비트 대신 8비트 부울 값을 사용한다면 데이터 구조는 8배의 크기가 될 것이다. 따라서 비트맵은 대량의 자원의 가용성을 표시할 때 일반적으로 사용된다.
디스크 드라이브가 좋은 예가 될 수 있다. 중간 크기의 디스크 드라이브는 디스크 블록이라 불리는 수천 개의 독립된 단위로 나누어진다. 각 디스크 블록의 가용여부를 나타내기 위해 비트맵을 사용할 수 있다.

계산 환경

전통적 계산(Traditional Computing)

(생략)

이동형 컴퓨팅(mobile computing)

(생략)

분산 시스템(Distributed Systems)

(생략)

클라이언트 서버 계산(Client-Server Computing)

(생략)

피어 간 계산(Peer-to-Peer Computing)

(생략)

가상화(Virtualization)

넓게 말하면 가상화는 에뮬레이션을 포함하는 소프트웨어 집단의 한 구성원이다. 에뮬레이션은 소스 CPU 유형이 목표 CPU 유형과 다를 때 사용된다.
에뮬레이션은 비용이 크다. 소스와 목표 CPU가 비슷한 성능 수준일 경우 에뮬레이트된 코드는 원래 코드보다 훨씬 느리게 수행된다.
에뮬레이션의 일반적 예는 컴퓨터 언어가 기계어 코드가 아니라 고급 수준 형태로 수행되거나 또는 중간 형태로 번역되었을 경우 발생한다.
이와 달리 가상화는 특정 CPU를 위해 컴파일 된 운영체제가 동일 CPU 용의 다른 운영체제 내에서 수행된다. 가상화는 다수 사용자가 작업을 병행 수행하기 위한 방법으로 IBM 대형 컴퓨터에 처음 등장하였다.
(생략)

클라우드 컴퓨팅

클라우드 컴퓨팅은 계산, 저장장치는 물론 응용조차도 네트워크를 통한 서비스로 제공하는 계산 유형이다.
많은 유형의 클라우드 하부구조 내에 전통적인 운영체제가 존재한다. 그 위에는 사용자 프로세스가 수행되는 가상기계를 관리하는 VMM이 있다.

실시간 내장형 시스템(Real-Time Embedded Systems)

내장형 시스템은 현재 가장 유행하는 컴퓨터 형태로 이 장치들은 자동차 엔진, 공장용 로봇에서 VCR, 전자파 오븐 등 어느 곳에서나 볼 수 있다. 이 장치들은 아주 특정한 작업만 수행하는 경향이 있다. 이 장치들이 수행되는 시스템은 매우 원시적이며 따라서 운영체제도 제한된 기능만을 제공한다.
이 내장형 시스템들은 매우 다양하다. 어떤 시스템은 UNIX와 같은 범용 운영체제를 수행시키면서 특수 목적을 가진 응용 프로그램을 수행시키는 형태를 갖는다.
다른 시스템은 필요한 기능만 제공하는 내장형 운영체제를 가지고 있는 하드웨어의 형태를 취한다.
또 다른 시스템은 운영체제 없이 필요한 작업을 수행하는 응용 전용 칩(ASICs, Application-specific integrated circuits)만을 갖는 하드웨어 장치들이다.
내장형 시스템은 거의 언제나 실시간 운영체제를 수행한다. 실시간 시스템은 처리기의 작동이나 데이터의 흐름에 엄격한 시간 제약이 있을 때 사용된다. 따라서 실시간 시스템은 종종 전용 응용에서 제어 장치로 사용된다.
감지기가 데이터를 컴퓨터로 가져온다. 컴퓨터는 데이터를 분석하고 감지기의 입력을 변경할 수 있도록 제어를 조정할 것이다.
과학 실험을 제어하는 시스템, 의학 영상 시스템, 산업 제어 시스템, 그리고 몇몇 디스플레이 시스템 등이 실시간 시스템이다. 또한 일부 자동차 엔진 연료 분사 시스템, 가전 기기 제어기, 그리고 무기 시스템들도 실시간 시스템에 포함된다.

오픈소스 운영체제

(생략)