해당 내용은 공룡책(Operating System Concepts 10th Ed. : Abraham Silberschatz, Peter Baer Galvin, Greg Gagne)과 대학 강의를 기반으로 재구성하여 정리한 공부 내용입니다.
1. 운영체제 서비스(Operating System Services)

사용자 인터페이스(User interface)
거의 모든 운영체제가 UI를 제공한다.
가장 일반적으로 그래픽 사용자 인터페이스(GUI)가 사용되며, 터치스크린 인터페이스, 명령어 라인 인터페이스(CLI)가 사용되기도 한다. (여러 형태를 모두 제공하기도 함)
프로그램 수행(program execution)
시스템은 프로그램이 정상적이든, 비정상적이든(오류를 표시하면서) 메모리에 적재해 실행을 끝낼 수 있어야 한다.
반드시 메모리에 적재가 되어야 CPU가 명령어를 읽어 실행할 수 있다.
입출력 연산(I/O operation)
실행 중인 프로그램은 파일이나 입출력 장치가 연관된 입출력을 요구할 수 있다.
입출력 연산은 프로그램이 컴퓨터 외부의 데이터를 받아들이거나 외부로 데이터를 내보내는 작업이다.
효율과 보호를 위해 사용자가 직접 입출력 장치를 제어할 수 없고, 운영체제가 입출력 수행의 수단을 제공한다.
파일 시스템 조작(file system manipulation)
프로그램은 파일을 읽고 쓰고, 생성하고 삭제하고, 찾고, 파일의 정보를 열거하고, 권한 관리를 이용해 접근을 허가하거나 거부할 수 있어야 한다.
통신(communication)
프로세스는 동일한 컴퓨터에서 실행되고 있는 프로세스 사이에서, 또는 네트워크로 연결되어 있는 서로 다른 컴퓨터 시스템 상에서 실행되는 프로세스 사이에서 정보를 교환할 수 있어야 한다.
통신은 공유 메모리를 통해서, 또는 메시지 전달 기법(message passing)으로 정보 패킷이 운영체제에 의해 프로세스 사이를 이동하도록 구현될 수 있다.
오류 탐지(error detection)
운영체제는 항상 모든 가능한 오류를 의식하고 있어야 하고, 올바르고 일관성 있는 계산을 위해 각 유형의 오류에 대해 적당한 조치를 해야 한다.
오류는 CPU, 메모리 하드웨어, 입출력 장치, 사용자 프로그램에서 일어날 수 있다.
디버깅 설비(Debugging facilities)는 시스템을 효율적으로 사용할 수 있는 사용자와 프로그래머의 능력을 향상시킨다.
+ 사용자 도움 목적이 아닌, 시스템 자체 효율적인 동작을 보장하기 위한 기능들
자원 할당(resource aloocation)
다수의 프로세스나 다수의 작업이 동시에 실행될 때 자원을 각각 할당해주어야 한다.
여러 가지 종류의 자원들 중 CPU 사이클, 메인 메모리, 파일 저장장치들은 특수한 할당 코드를 가질 수 있지만, 그외 입출력 장치와 같은 것들은 요청과 릴리즈 메커니즘에 따른다.
기록 작성(logging)
어떤 프로그램이 어떤 종류의 컴퓨터 자원을 얼마나 많이 사용하는지를 추적하기를 원한다.
이는 회계(Accounting), 사용 통계를 내기 위해 사용된다.
보호(protection)와 보안(security)
다중 사용자 컴퓨터 시스템 또는 네트워크로 연결된 컴퓨터 시스템에 저장된 정보의 소유자는 여러 프로세스가 병렬적으로 수행될 때 서로 방해하지 않도록 해당 정보의 사용을 통제하기를 원한다.
보호는 시스템 자원에 대한 모든 접근이 통제되도록 보장하는 것을 필요로 하며, 외부로부터의 시스템 보안은 각 사용자가 자원에 대한 접근을 원할 때 사용자 인증을 필요로 한다. 더 나아가 네트워크 어댑터 등과 같은 외부 입출력 장치들을 부적합한 접근 시도로부터 지키고, 침입 탐지를 위해 모든 접속을 기록해야 한다.
2. 사용자와 운영체제 인터페이스(User and Operating System Interface)
명령 인터프리터(Command Interpreter)
운영체제 대부분은 명령 인터프리터(=Command Line Interface, CLI)를 프로세스가 시작되거나 사용자가 처음 로그인할 때 실행되는 특수한 프로그램으로 취급한다.
커널에서 구현되기도 하고, 시스템 프로그램에 의해 구현되기도 한다.
여러 명령 인터프리터를 제공하는 시스템에서는 이를 셸(shell)이라 부르며, bash, zsh, PowerShell 등이 있다.
주요 기능은 사용자로부터 명령을 가져와 실행하는 것인데, 두 가지 일반적인 방식이 존재한다.
1) 명령 인터프리터 자체가 명령을 실행할 코드를 내장한 경우
각 명령이 구현 코드를 요구하므로 제공될 수 있는 명령의 수가 명령 인터프리터의 크기를 결정해 추천하지 않는다.
2) 시스템 프로그램에 의해 대부분의 명령을 구현하는 경우
명령 인터프리터는 명령을 알지 못 하고, 메모리에 적재해 실행할 파일을 식별하기 위해서만 명령을 사용한다.
명령어 이름으로 된 파일을 찾아서, 해당 파일을 메모리에 적재하고, 이를 매개변수에 대해 실행한다. 이때 파일에는 명령과 관련된 로직이 파일 내의 코드로 정의되어 있다.
이 경우 적합한 프로그램 로직을 가진 새로운 파일을 생성함으로써 시스템에 새로운 명령을 쉽게 추가할 수 있다.
→ 명령 인터프리터가 아주 작아질 수 있으며, 새로운 명령을 추가하기 위해 변경될 필요도 없다.
그래픽 기반 사용자 인터페이스(Graphical User Interface)
데스크톱 기반으로 모니터를 통해 프로그램, 파일, 시스템 기능 등을 나타내는 화면 상의 이미지인 아이콘에 대해 사용자가 마우스를 움직여 윈도 메뉴 시스템을 사용한다. → 사용자 친화적
마우스 버튼을 눌러 프로그램을 호출하거나 파일 또는 디렉터리(폴더)를 선택할 수 있다.
1970년대 Xerox PARC 연구 센터에서 기인하였다.
터치스크린 인터페이스(Touch-Screen Interface)
모바일 시스템에는 기존의 CLI나 마우스 및 키보드 시스템이 실용적이지 않음 → 터치스크린 기기를 위해 새로운 인터페이스가 요구되었다.
사용자는 터치스크린에서 제스처를 취하여 상호작용하며, 가상의 키보드를 시뮬레이션한다.
인터페이스의 선택(Choice of Interface)
CLI와 GUI 사용의 선택은 개인의 선호와 능력, 필요에 따라 달라질 수 있다.
몇몇 시스템은 GUI를 통해서는 시스템 기능의 일부만 이용할 수 있고 나머지 기능은 CLI를 사용해야만 하기도 하며, 요즘 시스템의 경우 모든 인터페이스를 제공하기도 한다.
셸 스크립트(shell scripts): 필요한 절차를 파일로 저장하여 프로그램을 실행하듯이 CLI에 의해 번역되면서 실행될 수 있게 해준다. (실제로 기계어 코드로 컴파일되는 것은 아님)
- Microsoft Windows: CLI 'command' shell과 함께 GUI 사용
- Apple Mac OS X: 'Aqua' GUI와 함께 UNIX 커널을 이용한 CLI 사용
- Unix와 Linux: optional GUI와 함께 CLI 사용 (CDE, KDE, GNOME)
3. 시스템 콜(System Calls)
시스템 콜: 운영체제에 의해 제공된 서비스에 대한 인터페이스를 프로그래밍한 것
일반적으로 high-level language(C, C++)로 작성되어 있다.
주로 응용 프로그래밍 인터페이스(application programming interface, API)에 의해 프로그래밍하여 시스템 콜을 간접적으로 호출한다.
왜?
→ 프로그램의 호환성(플랫폼 독립성): 같은 API를 지원하는 어느 시스템에서든 컴파일되고 실행 가능함을 기대할 수 있다.
→ 시스템 콜은 더 자세한 명세가 필요하고 프로그램상에서 작업하기 어려워, API를 통해 호출하는 게 더 쉽기 때문이다.
추상화, 유지보수 용이
API는 각 함수에 전달되어야 할 매개변수들과 프로그래머가 기대할 수 있는 반환 값을 포함하여 프로그래머가 사용 가능한 함수의 집합을 명시한다.
일반적으로 사용되는 API
1) Windows 시스템을 위한 Windows API
2) POSIX 기반 시스템을 위한 POSIX API(거의 모든 버전의 UNIX, Linux, Mac OS X)
3) JVM(Java Virtual Machine)에서 실행될 수 있는 프로그램을 위한 Java API
모든 운영체제는 고유의 시스템 콜 이름을 가진다.
시스템 콜의 구현


실행시간 환경(RTE)은 시스템 콜 인터페이스를 제공한다.
시스템 콜 인터페이스는 API 함수의 호출을 가로채어 필요한 운영체제 시스템 콜을 부른다.
각 시스템 콜에는 번호가 할당되고, 시스템 콜 인터페이스는 이 번호에 따라 색인되는 테이블을 유지하고 있어, 번호를 이용해 의도한 시스템 콜을 식별하고, 호출하면 시스템 콜의 상태와 반환 값을 돌려준다.
호출자는 시스템 콜 구현에 대해 아무것도 알 필요가 없으며 API를 준수하고 시스템 콜의 결과로 OS가 무엇을 할 것인지만 알면 된다.
운영체제 인터페이스에 대한 대부분의 상세 내용은 API에 의해 프로그래머에게 숨겨지고, RTE에 의해 관리된다.
운영체제에 매개변수를 전달하는 방법
1. 매개변수를 레지스터 내에 전달
2. 매개변수를 메모리 내의 블록이나 테이블에 저장하고, 블록의 주소를 레지스터 내에 매개변수로 전달
3. 매개변수를 프로그램에 의해 스택에 push하고, 운영체제에 의해 pop
가장 간단한 방법은 1번이지만, 레지스터보다 많은 매개변수가 존재하는 경우 개수나 길이 제한이 없는 블록이나 스택 방법을 사용할 수 있다. (Linux의 경우 5개 이하이면 1번을, 이상이면 2번을 사용)
시스템 콜의 유형
- 프로세스 제어(Process Control)
- end, abort(중지) → 오류 발생으로 트랩이 유발된 경우 memory dump, 오류 메시지 생성 → dump는 Debugger에 의해 버그가 있는지 검사될 수 있다.(한 스텝씩 실행)
- load, execute
- 프로세스 생성, 종료
- 프로세스 속성 획득·설정
- wait for time
- wait event, signal event
- allocate/free memory
- 여러 프로세스 간 공유된 데이터 접근을 제어하기 위한 Lock
- 파일 조작(File Manipulation)
- 파일 생성, 삭제, open, close
- read, write, reposition(위치 변경)
- 파일 속성 획득·설정
- 장치 관리(Device Management)
- request/release devices
- read, write, reposition
- 장치 속성 획득·설정
- logically attach/detach(부착/분리) devices
- 정보 유지(Information Maintenance)
- get/set time, date, system data
- 프로세스, 파일, 장치 속성 획득·설정
- 통신(Communication)
- 통신 연결의 생성, 제거
- message passing model: 호스트나 프로세스 이름으로 식별해 클라이언트에서 서버(수신 디먼)로 메시지를 전달한다.
- shared-memory model: 어떤 프로세스가 다른 프로세스가 가진 메모리 영역에 접근할 때 시스템 콜을 사용한다.
- 상태 정보 전달
- 원격 장치의 부착 및 분리
- 보호(Protection)
- get/set file permissions
- 자원 접근 제어, 사용자 접근 허가
4. 시스템 서비스(System Services)
시스템 서비스 = 시스템 유틸리티 = 시스템 프로그램: 프로그램 개발과 실행을 위해 더 편리한 환경 제공
- 파일 관리: 파일과 디렉토리를 create, delete, copy, rename, print, dump, list, manipulate
- 상태 정보: 프로그램이 시스템에 요청하는 상태 정보 제공; 날짜, 시간, 가용메모리, 가용 디스크 공간, 사용자 수, 성능, 로깅, 디버깅 정보 등. 파일로 포맷하여 print하거나 GUI 윈도에 표시. 또는 환경 설정 정보를 저장 및 검색할 수 있는 등록(registry) 기능을 지원하기도 한다.
- 파일 변경: text editor를 사용해 파일 내용을 생성 및 수정. 파일 내용을 검색하거나 변환하기 위한 특수 명령어가 제공되기도 한다.
- 프로그래밍 언어 지원: 컴파일러, 어셈블러, 디버거 및 인터프리터가 제공되거나 별도 다운로드 가능하다.
- 프로그램 load와 execution: 절대 로더, 재배치 가능 로더, 링키지 에디터, 중첩 로더, 디버깅 시스템 등 제공
- 통신: 프로세스, 사용자, 다른 컴퓨터 시스템들 간 가상 접속을 이루기 위한 메커니즘 제공. 다른 사용자 화면으로 메시지 전송, 웹 페이지 브라우징, 전자 우편 메시지 보내기, 원거리 로그인, 파일 전송 등
- 백그라운드 서비스: 부트 시에 특정 시스템 프로그램을 시작시키는 프로세스들 중 일부 프로세스는 부트 시에 할 일을 끝내면 종료되고, 일부는 시스템 셧다운 시까지 계속 실행된다. 후자의 경우 서비스, 서브시스템, 디먼이라 하고, 네트워크 연결, 프로세스 스케줄러, 시스템 오류 감시 서비스 및 출력 서버 등을 제공한다. 운영체제가 kernel context가 아닌 user context에서 실행되어야 하는 경우 디먼을 이용해 실행할 수 있다.(필요시 자원 활용)
사용자 대부분이 보는 운영체제의 관점은 실제 시스템 콜에 의해서보다는 시스템 프로그램과 응용 프로그램에 의해 정의된다.
같은 하드웨어상에서 사용자는 여러 UI에 순차적 또는 병행하게 노출된다.
5. 링커와 로더(Linkers and Loaders)
6. 응용 프로그램이 운영체제마다 다른 이유(Why Applications Are Operating System Specific)
7. 운영체제 설계 및 구현(Operating System Design and Implementation)
설계
운영체제에 대한 요구를 정의하는 문제를 해결하는 정답은 없다.
다양한 시스템에서 다른 요구 조건들이 다른 환경을 위해 다양한 해결 방법을 낳을 수 있다.
요구 조건은 사용자 목적과 시스템 목적 두 그룹으로 나눌 수 있다.
사용자 목적(User goals): 사용하기 편리하며, 배우기 쉽고, 믿을 수 있고, 안전하고, 신속해야 함
시스템 목적(System goals): 설계, 구현, 유지 보수가 쉽고, 적응성, 신뢰성, 무오류, 효율성을 가져야 함
운영체제 명세와 설계에 대한 일반적인 원칙
: 기법(mechanism)으로부터 정책을 분리하는 것
→ 정책은 장소가 바뀌거나 시간이 흐름에 따라 바뀔 수 있으므로, 여러 정책에서 사용되기 위해서는 융통성 있는 일반적인 메커니즘을 사용하는 것이 바람직하다. → 유연성 및 모듈성 향상
Mechanism: 어떤 일을 어떻게(How) 할 것인가를 결정
Policy: 무엇(What)을 할 것인가를 결정
구현
초기 운영체제는 어셈블리 언어로 작성 → 현재 대부분 C 또는 C++과 같은 고급 언어로 작성
여러 언어를 함께 사용하는 것도 흔하다. (커널의 최하위 레벨은 어셈블리 언어, 메인 바디는 C, 상위 레벨은 C나 C++ 등)
운영체제 구현에서의 고급 언어 사용
장점: 빠르고 간결하고 이해하고 디버그하기 쉬운 코드 작성. 다른 하드웨어로 이식(port) 용이; Emulation
단점: 속도가 느리고 저장 장치를 많이 사용.
8. 운영체제 구조(Operating System Structures)
단순 구조(Simple Structure)
MS-DOS: 최소한의 공간에서 최대한의 공간을 제공하도록 작성
모듈로 나누지 않음
모놀리식 구조(Monolithic Structure)
최초의 UNIX 운영체제: 제한적인 구조를 가지고, 커널과 시스템 프로그램 두 부분으로 구성됨
전통적인 UNIX 운영체제는 계층들로 이루어짐

커널
→ 시스템 콜 인터페이스 아래와 물리적 하드웨어 위의 모든 것
→ 시스템 콜을 통해 파일 시스템, CPU 스케줄링, 메모리 관리, 다른 운영체제 기능 제공
모놀리식 구조
구조가 없는 것. 커널의 모든 기능을 단일 주소 공간에서 실행되는 단일 정적 이진 파일에 넣는 것.
대부분의 기능을 단일 커널에 밀집
단순하지만 구현 및 확장, 유지보수 어려움. 버그 원인이나 오류 구분 어려움.
동일한 메모리에서 실행하여 한 부분에서 발생한 문제가 시스템 전체에 영향 → 악성 코드 피해
But 속도와 효율; 시스템 콜 인터페이스에 오버헤드가 거의 없고 커널 안에서의 통신 속도가 빠름
계층적 접근(Layered Approach)

운영체제가 여러 개의 층으로 나뉘어져 최하위 층(층 0)은 하드웨어, 최상위 층(층 N)은 사용자 인터페이스가 된다.
비슷한 기능을 수행하는 요소를 그룹화하여 계층적으로 구성된다.
레이어들은 오직 자신보다 하위층에 의해 제공된 서비스와 기능(연산)만을 사용하도록 선택된다.
사용자 프로세스의 요청을 수행할 때 여러 계층을 거쳐야 한다. (오버헤드 발생)
But 모듈화로 디버깅과 시스템 검증 단순화 지원 → 시스템의 설계나 구현이 간단해진다.
마이크로커널(Microkernel)

Mach: 마이크로커널 접근 방식을 사용하여 커널을 모듈화한 운영체제; 모든 부수적인 구성요소를 별도의 주소 공간(user space)에 존재하는 사용자 수준 프로그램으로 구현하여 운영체제를 작은 커널로 간소화한 방식
Mac OS X의 Darwin에서 부분적으로 사용
마이크로커널은 일반적으로 통신 설비 외에 추가로 최소한의 프로세스와 메모리 관리를 제공(IPC, CPU 스케줄링 등)
mesagge passing에 의해 클라이언트 프로그램과 사용자 공간에서 수행되는 다양한 서비스 간의 통신 제공
→ 클라이언트 프로그램과 서비스는 직접 상호 작용하지 않고 마이크로커널과 간접적으로 상호 작용
장점:
운영체제 확장이 쉬움(새로운 서비스를 사용자 공간에 추가, 커널 변경 불필요)
운영체제를 한 하드웨어로부터 다른 하드웨어로 이식이 쉬움(서비스 대부분을 사용자 프로세스로 실행하기 때문)
높은 보안성과 신뢰성 제공
단점:
message passing; 커널 공간과 사용자 공간 사이의 잦은 전환으로 오버헤드 발생, 성능 저하
잦은 컨텍스트 스위칭 발생 가능
모듈(Modules)
가장 최근 운영체제는 loadable kernel modules(LKM)으로 구현 (linux, Solaris 등)
커널은 핵심적인 구성요소의 집합만 가지고, 부팅 때 또는 실행 중에 부가적인 서비스들을 모듈을 통하여 동적으로 링크
즉 커널을 여러 개의 모듈로 나누어 독립적으로 로드/언로드할 수 있게 구성
객체 지향적인 접근으로 사용하여, 각 구성요소가 모듈로 분리되어 있고 인터페이스를 통해 통신
여전히 하나의 주소 공간에 있지만(모놀리식 구조), 필요 없는 기능은 빼고 새로운 기능은 모듈로 쉽게 추가할 수 있다.
전체적으로는 각 부분이 정의되고 보호된 인터페이스를 가진다는 점에서 계층 구조와 닮았지만, 모듈에서 임의의 다른 모듈을 호출할 수 있다는 점에서 계층 구조보다 유연하다.
중심 모듈이 핵심 기능만 가지고 있고 다른 모듈과 통신한다는 점에서는 마이크로커널과도 비슷하지만, 통신하기 위해 메시지 전달을 호출할 필요가 없기 때문에 더 효율적이다.
하이브리드 시스템(Hybird Systems)
대부분의 운영체제는 엄격하게 하나의 구조만을 채택하지 않고 다양한 구조를 결합해 문제를 해결하려는 혼용 구조
Linux나 Solaris는 커널 전체가 하나의 주소 공간에 존재해 모놀리식 구조이지만, 모듈을 사용하여 동적으로 새로운 기능을 추가한다.
Windows는 대체적으로 모놀리식 구조이지만, personalities라 알려진 분리된 서브시스템을 지원해 마이크로커널의 형태를 띈다. (+동적으로 로더블 커널 모듈도 지원한다.)
Apple Mac OS X는 UI 층은 Aqua를 사용하며, 응용 프로그램 프레임워크는 Cocoa를 사용하고, 커널 환경은 Mach 마이크로커널과 BSD Unix 커널로 구성된 Darwin과 동적 로더블 모듈 개발을 위한 I/O 키트를 제공한다.
9. 운영체제 빌딩과 부팅(Building and Booting an Operating System)
운영체제 생성(Operating System Generation)
운영체제는 하나의 특정 기기 구성에 맞게 설계, 코딩 및 구현할 수 있지만, 일반적으로 모든 종류의 컴퓨터에서 실행되도록 설계된다.
SYSGEN 프로그램: 하드웨어 시스템의 특정 구성에 관한 정보 제공
시스템 부트(System Boot)
시스템 부팅(System booting): 커널을 로드하여 컴퓨터를 시작하는 과정
부팅 과정
1. 부트스트랩 프로그램 또는 부트 로더라고 불리는 작은 코드(Firmware ROM에 있는 BIOS)가 커널의 위치를 찾는다.
→ 이 초기 부트 로더가 디스크에 정해진 위치에 있는 두번째 부트 로더인 boot block을 ROM에 로드한다.
2. 커널이 메모리에 로드되고 실행된다.
3. 커널이 하드웨어를 초기화한다.
4. 루트 파일 시스템이 마운트된다.
GRUB: Linux 및 UNIX 시스템을 위한 오픈소스 부트스트랩 프로그램. 커널을 선택할 수 있게 해준다.
10. 운영체제 디버깅(Operation System Debugging)
장애 분석(Failure Analysis)
디버깅(Debugging): 하드웨어와 소프트웨어에서의 시스템 오류(bugs)를 발견하고 수정하는 행위
프로세스가 실패하면 운영체제는 오류 정보를 로그 파일에 기록하고, 프로세스가 사용하던 메모리를 캡처한 코어 덤프(core dump)를 발생시켜 차후 분석을 위해 파일로 저장한다. 초창기 시절에 메모리를 core라고 칭했었다.
→ 디버거에 의해 검사된다.
운영체제 커널 장애(crash)의 경우 마찬가지로 오류 정보가 로그 파일에 저장되고, 메모리 상태가 크래시 덤프(crash dump)에 저장된다.
성능 관찰 및 조정(Performance Monitoring and Tuning)
+참고
성능 조정(performance tuning)을 통해 프로세스의 병목 지점(bottleneck)을 제거하여 시스템 성능을 최적화할 수 있다.
이를 측정하고 표시하는 도구는 카운터(Counters), 추적(Tracing)을 사용할 수 있다. (ex. top 프로그램, Windows Task Manager)
프로파일링(Profiling)은 통계적 경향을 찾기 위해 주기적으로 지시 포인터를 샘플링하는 것이다.
Kernighan's Law: 디버깅은 코드를 작성하는 것보다 두 배 어렵다. 그러므로 여러분이 가능한 한 영리하게 코드를 작성하는 것이, 정의에 따라 디버깅하는 것보다 현명하다.
Solaris, FreeBSD, Mac OS X에서의 DTrace 도구: 시스템 실시간 정보를 제공
'Study > OS' 카테고리의 다른 글
[운영체제] 5. CPU Scheduling (0) | 2025.04.18 |
---|---|
[운영체제] 4. Threads & Concurrency (1) | 2025.04.18 |
[운영체제] 3. Process (3) | 2025.04.17 |
[운영체제] 1. Introduction (2) | 2025.04.06 |