Not only the concepts, let's learn how they work.
OS Services
OS service의 관점
•
OS는 프로그램과 하드웨어 사이에서, 프로그램의 실행을 위한 환경을 제공한다.
◦
Applications (User programs, Other system programs)랑 Hardware 사이에 OS가 존재함을 볼 수 있다.
◦
OS는 유저와 시스템에게 다양한 서비스를 제공한다.
OS Services for User Support
Remind: OS는 유저와 시스템에게 다양한 서비스를 제공한다.
•
UI (User Interface)
◦
CLI : Command Interpreters (shell이라고도 불림)
$ rm file.txt
→ shell이 path에서 'rm' 프로그램을 찾아서, 메모리에 로드해서, 'file.txt'를 파라미터로 해서 실행한다.
◦
GUI
•
Program Execution
◦
시스템은 프로그램을 메모리에 로드하고, 실행하고, 실행을 끝낼 수 있어야 한다.
•
I/O operations
◦
OS는 효율과 보안을 위해, 사용자가 직접 입출력 장치를 조작하지 않고, OS를 거치도록 해야 한다.
•
File-system manipulation
◦
파일 읽기, 쓰기, 생성, 삭제, 검색. + 사용자가 파일에 접근하지 못하도록 막기도 한다.
•
Communications
◦
프로세스끼리 정보 교환
▪
Shared memory : 여러 프로세스가 메모리의 한 부분을 공유하도록
▪
Message passing : 프로세스 간에 message(정보)를 주고받는 것.
Message passing이 Shared memory보다 더 느리다.
•
Error detection
◦
OS는 하드웨어 수준에서 발생하는 에러 (Memory error, Power failure, ...), 소프트웨어 수준에서 발생하는 에러 (bit-flip, ...)를 탐지하고, 고칠 수 있어야 한다.
OS Services for Efficient Operation
•
Resource Allocation
◦
자원 : CPU 사이클, 메모리 공간, 메모리 대역폭, 파일 시스템 공간, 파일 입출력 대역폭, ...
•
Accounting
◦
어떠한 프로세스가 자원을 얼마나 사용했는지 계속해서 추적
•
Protection and Security
◦
Multi-user environment에서, 시스템 자원으로의 모든 접근은 통제되어야 한다.
▪
동시에 Resource에 접근하는 프로세스들이 많을 수도 있고, Visibility 문제 등...
▪
프로세스끼리는 서로 방해하지 않아야 한다.
System calls
예시) 파일 하나 열어서 다른 파일로 copy하는 작업. 여기서는 어떤 시스템 콜들이 사용되는가?
1.
사용자로부터 파일 이름 입력받기 - 시스템 콜을 반드시 사용해야만 한다. 키보드 입력, GUI에서도 마우스 입력, 창 띄우기 등등...
2.
두 파일을 open한다. - 파일 열기, 에러나면 에러 표시하기 등등... 이런게 다 시스템콜이다
3.
데이터 복사해서 Destination file에 write. - 어느 단위만큼 읽고 쓰고 반복. loop. 이 단계에서 또 에러 생기면 에러 출력 등등...
4.
Close both files. - 당연히 시스템콜
5.
전송 완료 메시지 표시, 전송 끝, 프로그램 종료
Open, close는 추상적인 단어.
•
Conclusion : 시스템 콜들은 간단한 작업에도 엄청 많이 쓰인다.
◦
1초에 몇천 개 나온다.
•
프로그래머들은 API를 이용해서 시스템 콜을 간접적으로 사용한다.
◦
API : 라이브러리와 함수의 집합
◦
Windows API, POSIX API, Java API 등이 있다.
◦
API끼리 계층을 이루기도 한다. 상위 API가 하위 API를 부른다던가...
▪
Java API는 libc를 사용한다.
•
그럼 왜 API를 써서 시스템 콜을 간접적으로 call하는가? 직접 call하지 않고 API를 부르게 하는 이유?
◦
시스템 콜들을 직접 사용하는 것은 어렵다.
▪
파라미터, 사용법 등...
◦
API는 사람이 봤을 때 사용하기 편하게 이루어져 있다.
버퍼링 같은 부가적인 서비스들을 제공하므로, 프로그래머 입장에서는 API 쓰는게 훨씬 편하다.
◦
Portability
▪
컴퓨터마다 전혀 다른 내부 시스템 콜 구조를 가지고 있더라도, 우리는 API를 기준으로 짜 놨기 때문에 그대로 동작한다.
▪
컴퓨터에 맞게 프로그램을 수정할 필요가 없다.
System Call Interface
User program이 어떠한 과정으로 System call을 부르는가?
1.
User program(libc 등도 포함)이 open() 등 System call을 호출한다.
2.
System Call Interface에서 핸들링. User mode → Kernel mode로 전환.
3.
System call function pointer에서 sys_open() 등 함수 호출, 작업 수행.
4.
다시 System Call Interface로 넘어가서, Kernel mode → User mode로 전환.
•
Caller는 시스템 콜이 어떻게 구현되어 있는지 알 필요 없다.
단순히 시스템 콜 이름, 파라미터, 무엇을 리턴하는지 정도만 알면 된다.
System Call Types
시스템 콜들을 6개 카테고리로 분류해볼 수 있다.
•
Process control (프로세스 제어)
◦
fork, exec, exit, ...
•
File manipulation (파일 관리)
◦
create, open, close, read, write, lseek
•
Device manipulation (장치 관리)
◦
open, close, read, write, ioctl
•
Information maintenance (정보 유지)
◦
time, date, dump, pid
•
Communications (통신)
◦
open, close, connect, accept, read, write, send, recv, pipe, mmap, sendfile, ...
•
Protection (보호)
◦
chmod, umask, chown
System call types : Process Control
Remind : Difference btw Program and Process
Process : instance of Program.
하나의 프로그램이 여러 프로세스를 가질 수 있다. 프로그램은 그저 코드덩어리일 뿐.
Process Control
•
컴퓨터에는 많은 프로세스들이 돌아가고 있다.
•
프로세스의 생성/종료, 메모리 할당/해제, .... OS는 프로세스들을 관리해야 한다.
예시 시나리오 몇 가지
•
Error handling
◦
프로세스를 종료하려면 → Clean-up 과정이 필요하다.
◦
Memory dump를 만든다.
▪
프로그램이 오류로 인해 종료되었다면, 그 때의 메모리 상태 복사본을 만들어 두면, 프로그래머가 Memory dump를 보고 어디가 잘못되었는지 디버깅할 수 있다.
◦
메시지를 출력하고, 프로세스를 끝낸다.
◦
다음 실행할 명령어를 결정하고, 실행한다.
•
다른 프로그램 로딩, 실행
◦
새로운 프로세스가 종료되면 어디로 Control을 넘겨줄 것인가
◦
Concurrently하게 실행할 것인가, 말 것인가
•
Multiprogramming에서도 프로세스들을 관리해야 한다.
◦
프로세스 Attributes들을 Get/Set (Priority, Time limit, Resource limit, ...)
◦
필요 없는 프로세스들을 선택적으로 종료
System call types : Communications
Communication : 네트워킹, 소켓 프로그래밍 등...
커뮤니케이션에는 두 가지 모델(접근, 구현)이 있다.
•
Message passing
◦
한 프로세스가 다른 프로세스에세 메시지 전달.
◦
Connection이 처음에 먼저 열려있어야 한다.
◦
프로세스는 메시지 전송 요청만 하고, 실제 전달은 OS에 의해 완료된다.
◦
장점
▪
OS가 전달해주기 때문에 동기화 문제 X
◦
단점
▪
성능이 다소 떨어진다.
•
Shared-memory :
◦
기본적으로, 프로세스는 다른 프로세스의 메모리 공간에 접근할 수 없다.
◦
공통으로 사용하는 메모리 공간을 만들고, 서로 공간을 공유한다.
◦
프로세스들은 OS에게 시스템 콜로 Shared memory 접근 요청을 보내고, OS가 이를 받아 프로세스들에게 알린다.
◦
장점
▪
성능이 좋음
◦
단점
▪
동기화 문제. 각 프로세스들이 언제 메모리에 접근할지 모른다.
Other types
•
File management
•
Device management
•
Information maintenance
OS Design and Implementation
OS 설계의 목표
•
사용자 관점에서의 목표
◦
사용이 쉬워야 한다. Reliable하고, 배우기 쉬워야 하고, 빨라야 한다.
•
시스템 관점에서의 목표
◦
구현이 쉬워야 한다. 관리(패치 적용 등)가 쉬워야 하고, 작동이 쉬워야 하고, Flexible하고, 효율적이어야 하고, 빨라야 한다.
막연한 요구 사항일 뿐이고, 명확한 해결책은 없다. 절충이 필요하다.
메커니즘(Mechanism)과 정책(Policy)을 분리 → OS 설계를 더 모듈화할 수 있다.
•
메커니즘 : 무엇을 어떻게 할 것인가?
•
정책 : 무엇이 되게 할 것인가?
정책이 더 상위의 레벨로, 메커니즘을 사용하는 것.
정책의 변경이 메커니즘의 변경을 필요로 한다면, 바람직한 설계가 아니다.
OS implementation
어셈블리어로 구현?
•
재미없고, 어렵고, 에러나기 쉽고, 포팅하기 어렵다.
High-level lang으로 구현하면? (C, C++: lowest high-level lang)
•
구현이 빠르고, 이해하기 쉽다.
•
개선된 컴파일러 → 개선된 코드가 생성된다.
•
포팅이 쉽다.
◦
MS-DOS 어셈은 에뮬레이터 필요. 리눅스는 C로 짜여져 있으므로 Native하게 구동 가능.
•
그래도 단점...
◦
성능 - 최적이 아닌 코드가 생성될 가능성이 있다.
▪
그래도 요즘 컴파일러 기술은 괜찮다.
▪
복잡한 Dependencies 다루기에는 컴파일러가 더 나음
▪
치명적인 코드(critical code)들은 High-level lang으로 먼저 작성 후, 최적화된 코드로 대체할 수 있다.
OS Structure
•
Monolithic structure
◦
모든 게 하나로 합쳐져 있다. 모듈로 나뉘어지지 않는다.
◦
결코 좋은 디자인이 아닌 걸 알지만, 고칠 수 없다. 모든 걸 다시 Rebuild할 강력한 이유가 없다.
•
Componentized, Modularized approach
◦
Component (Module) : Input, Output, Functions로 구성된, Well-defined된 시스템의 일부
Simple Structure
•
MS-DOS
◦
구조가 있긴 했지만, 그렇게 잘 나뉘어지지는 않았다.
◦
Application(사용자 프로그램)이 입출력 루틴에 직접 접근할 수 있었다.
▪
→ Application에 문제가 생기면, 전체 시스템에 문제가 생겼다.
•
Original UNIX
◦
사용자 계층과 하드웨어 사이의 'Kernel'이 모든 기능을 제공했다.
◦
이것도 여전히 하나의 계층이 너무 많은 일을 했다.
Layered Approach
•
OS가 여러 개의 레이어들로 나뉘어짐.
◦
Layer 0 (최하위 계층) : 하드웨어
◦
Layer 1, 2, 3, ...
◦
Layer M (최상위 계층) : User Interface
•
하나의 레이어는 인접한 레이어끼리만 통신한다.
◦
상위 레이어는 하위 레이어의 작업을 수행시키고,
하위 레이어는 상위 레이어에서 Call할 수 있는 작업을 제공한다.
•
장점
◦
구현이 간단하다. 디버깅이 쉽다.
▪
레이어들은 단지 자신의 바로 하위 레이어의 작업만 수행할 수 있도록 설계된다.
▪
최하위 계층부터 디버깅하다가, 어느 계층에서 오류가 발생하면 그 계층만 디버깅하면 된다.
•
단점
◦
레이어를 정의하는 것은 어렵다.
▪
OS의 어느 부분이 어느 레이어에 들어가야 하는지 명확히 정의할 수 없다.
◦
레이어들을 거치는 과정이 오버헤드를 야기할 수 있다.
Microkernels
•
커널을 최소화하자.
•
필수적이지 않은 함수들은 User-level library로 구현하자. → 대부분의 기능을 User space로 옮김.
•
마이크로커널 : 커널에서 핵심적인 요소만 남긴 가벼운 커널 → 마이크로커널은 서비스 콜 전달 등 단순한 기능만 제공.
•
Application과 서비스 사이의 효율적인 커뮤니케이션 제공
•
장점
◦
확장 가능
◦
포팅(다른 시스템에 이식)이 쉬움
◦
More secure and reliable
▪
대부분의 기능이 Kernel space가 아닌 User space에 있기 때문에, 문제 있는 서비스는 해당 부분만을 재시작하여 해결할 수 있음
▪
대부분의 코드가 Protected memory에서 실행되므로 안전
•
단점
◦
비교적 낮은 성능
▪
Context switching, System function call의 오버헤드 등