I. Operating System Services
밑바닥의 하드웨어 있고, 이 하드웨어를 컨트롤 하는 핵심적인 기술이 모아저 있는 커널이 위에 올라간다. 커널의 기능을 수행할 수 있는 System Call, 사용자가 편하게 시스템을 사용하기 위해 제공하는 User Interfaces가 있으며, 그 위에서 여러 어플리케이션들이 동작한다.
System call
: 운영체제만 수행할 수 있는 일을 요청하는 인터페이스 역할을 하는거 함수형태로 제공한다.
User interface service
-
Command-Line Interpreter (CLI)
① CMD : Window의 CLI
② Shell : Unix 계열 시스템의 CLI, 커널에 아무나 접근해서는 안되니 보호하기 위해 조개 껍데기처럼 둘러싸고 있어서 shell이라 부른다. OS 서비스를 이용할 수 있도록 하는 인터페이스 역할을 한다.
③ Bourne Shell : Sun Microsoft에서 제작한 shell
④ Bash (Born Again Shell) : Linux에서 사용하는 shell
-
Graphical User Interface (GUI)
: 입력 장치가 키보드와 마우스
-
Touch Screen Interface
: 입력장치가 손 (Microsoft의 Vision: ‘모든 것을 손 끝으로’)
System Programs
개발자가 쉽게 프로그래밍을 할 수 있는 것들을 제공하는 것들로 이루어져 있다. → Compiler
Compiler
: 유닉스 계열들은(유닉스 맥) 운영체제를 설치하면 기본적으로 내장(GCC)되어 있다. 하지만 윈도우는 컴파일러가 내장되어 있지 않다
- GPOS(General purposed operating system) : 범용 OS 위에서 어떤 프로그램을 돌리냐에 따라 그 os가 설치된 컴퓨터의 목적성이 뚜렷해 진다.
Linkers and Loaders
- Static Linking : 다른 영역으로 jump해서 수행하지 않아도 되니 빠르다. system library가 공통적으로 있지 않은 환경에서 좋을 수도 있다.
- Dynamic Linking : 프로그램에 중복되어 있지 않고, 컴파일 했을 때 나오는 바이너리 사이즈도 작아진다. 메모리에서 동작할 때도 Lib에 저장된 것을 한 번만 올리면 되니 효율적이다.
📂Compiling Process
-
Source code 작성 – 1.c , 2.c, 3.c … (High Level Language이기 때문에 CPU가 이해 불가)
-
compiler에게 c 코드를 넣는다
- Compiler = Preprocessor + Compiler(Translator)
- 전처리 : 전처리문(#include ~~) 이런게 있어 있다고 가정
- 번역 : 소스코드 하나 당 기계어로 번역된 코드가 나온다. -> 1.o , 2.obj (object file)
- 각각 따로 라서 실행이 안된다.
-
Linker
⇒ 각각 따로 라서 실행이 안 되는 코드들 + Library를 합쳐서 하나의 Executable Image(Program)로 만든다.
-
메모리에 Loader에 의해 program이 로드된다. ⇒ Process
[System Library]
⇒ dynamic linking에서 메모리 스페이스 한 곳에 Lib 를 다 집어 넣는데 이 부분을 부르는 명칭
- .dll (Dynamic Linked Library) in Windows
- .sa & .so (Shared Library) in Linux
System call service
operating system call이 이루어지면 mode change가 일어나야 하는데 trap 에 의해 일어난다.
- Example of standard API – 명세
System Call
: 커널과 사용자 프로그램을 이어주는 인터페이스 역할
➔ Open() Read() write() close() 와 같은 함수들
: 함수가 호출을이 되면 파일을 여는 함수를 찾기 위해 System Call Table(vector table)을 참조한다. System call table은 함수와 메모리 주소가 mapping되어 있는 table이다.
➔ HW 인터럽트도 timer, keyboard, mouse 등의 table 존재
- System call table, Interrupt vector
➔ 사용자 프로그램이 디스크에 있는 파일을 연다는 것은 파일 시스템에 접근한다는 의미다. 시스템에 접근하기 위해서는 커널 모드로 전환되어야 하는데, 이때 시스템 콜(트랩)을 사용한다. 메모리의 특정 주소 범위에는 어떤 동작들이 할당되어 있다.
- Parameter sysyem call 의 파라미터를 유저 프로그램에서 운영체제게에 넘겨줘야 할 때, 입력 파라미티를 레지스를 통해 전달
✅ 유닉스에서 만든 바이너리 파일을 윈도우에서 실행시키면 실행이 안된다 → 시스템 콜이 다르기 때문에
✅ 태생이 유닉스였던 아이들은 Posix 표준을 따르기 때문에 필수적인 시스템 콜들의 양식이 같기 때문에 Linux, Unix, Mac은 대체로 돌아간다.
✅ system library에서 구현이 되어 있는 함수의 이름과 실제 system call의 이름은 다를 수 있다.
ex) printf() / write()
II. Operating System Structure
A. Monolithic Kernel
: OS를 개발하는 관점으로 본다. OS의 모든 기능을 한 덩어리로 만든다.
- 장점 : 동작할 때 추가 메커니즘 필요 없이 OS가 가진 기능들을 빠르게 사용 가능하다.
- 단점: 의존성이 크기 때문에 유지보수 비용이 많이 든다. HW가 개선되고, HW가 바뀜으로 인해 할 수 있는 일이 많아지며 그것을 요구하는 SW도 많이 생기니 업데이트가 필요해진다. 한덩어리이기 때문에 유지보수를 하는데 힘들다.
- Unix, Linux
B. Micro Kernel
: 정말 필수적으로 필요한 기능만 커널 형태로 만들고 그 외의 추가되는 기능들은 일반 어플리케이션보다는 권한이 높은 어플리케이션의 형태로 만든다.
- Monolithic Kernel의 문제점을 해결하기 위해 기능을 분리시켜 만들었다.
커널의 발전사, 접근
✔ Monolithic structure
-
유지 보수 비용가 크다 = software engineeting issue가 발생할 수 있다
각 기능들 간의 의존성이 높아진다. 한곳을 고치려면 연쇄적으로 모든 곳을 수정해야한다.
-
덩치가 커서 전부 돌릴려면 하드웨어 성능이 좋아야 했다.
✔ Layered approach
: 이상적인 이야기, 하드웨어부터 유저 인터페이스까지 올라갈 때 사이사이에 있는 기능들을 독립적으로 따로 개발
✔ Microkernel Structure
: 원래는 제공해줘야 하는 기능을 어플리케이션으로 만들되 우선순위를 높여서 동작 시키게 하면 필요한 것 어플리케이션으로 실행시켜 돌린다.
- 원래는 한덩어리로 구현이 되어 있어서 trap을 걸 필요가 없었는데, 한 번만에 할 수 있는 일을 두세번 단계를 거쳐 해야한다
- Monolithic 에서는 커널에 존재했던 기능들이 마이크로 커널에서는 어플리케이션으로 구현이 되다 보니 실제로 하드웨어를 직접적으로 컨트롤하지 못한다. 따라서 커널한테 트랩을 걸어야 하고 이 트랩을 걸고 트랩 핸들링을 하는 과정이 오버헤드가 된다 → 이런 단점에도 불구하고 모노토닉 단점이 너무 크기 때문에..
✔ Modular approach
- 필수적으로 필요한 것을 빼고 나머지를 모듈화 하고, 그 모듈을 선택적으로 가져가서 컴파일을 시켜 돌린다.
- Solaris – Loadable Kernel Module
✅ 장점
- 개발하는 입장에서 모듈로 만들어 두면 유지보수를 할 때 편하고,
- 목적에 맞게 모듈을 선택해 필요한 것만 골라 운영체제를 컴파일하면 메모리를 많이 쓰지 않는다
✔ Hybrid approach
->Mac OS iOS Android
- Android – Linux 기반 위에 Framework가 올라간 것이니. 정확하게는 Android Framework라고 하는 것이 맞다