나도 공부한다/운영체제
03. 운영체제의 구조와 설계
꾸빵이
2021. 3. 29. 18:12
3-1. 운영체제의 구조
- 컴퓨터 시스템은 user, system and application programs, OS, hardware로 이루어져있음.
- 크게 User mode로 사용되는 User 메모리 공간과 Kernel mode로 사용되는 Kernel 메모리 공간으로 나뉨.
- User area에는 user, user application(OS를 제외한 모든 것. ex) cloud, 컴파일러)과 system program인 user interfaces(GUI, batch, command line)가 있음. user interfaces가 잘 와닿지 않는다면, 윈도우 하단바를 생각하면 됨.
- Kenel area에는 system call, services가 있음.
- 이때 user interface, system calls, services는 OS에 해당됨. 동적 메모리중에 OS 커널이 사용해야 하는 영역은 다 커널 영역으로 할당되고 나머지 영역은 유저 영역이 됨.
3-2. 운영체제의 설계
설계할때 소프트웨어의 구조를 고려해야하는 이유) 개발, 수정 및 디버깅, 유지보수, 확장이 쉬워짐.
설계 목표의 특성
- Fairness: 어떻게 해야 공평하게 관리할 수 있는지 -> 정책에 따라 시행(버츄얼 메모리)
- Real-time(실시간성): 멀티 미디어의 등장으로 중요해짐. 한치의 오차도 없어야하는 하드 리얼타임(ex) 원자력 발전소)과 조금의 오차가 발생해도 되는 소프트 리얼타임으로 나뉨.
- High performance: 리소스를 효율적으로 사용해야함.
- Scalability(규모 확장성) / Extensibility(기능 확장성): 건물을 예시로 들자면, 건물의 크기를 더 크게 하는것은 규모 확장성, 건물을 견고하게 하는 것은 기능 확장성임. 규모 확장성은 낭비되는 메모리도 고려해야함. 이 사이의 절충점을 찾는 것을 trade-off라고 함.
- Stability / Reliability / Robustness (신뢰성, 안정성)
- Security / Inregrity (보안성)
- Usability: 숙련되지 않은 사용자도 쉽게 사용.
- Compatibility (호환성): ex) 윈도우 7에서 쓰이는 어플리케이션이 윈도우 10에서도 동작
- Energy consumption: 에너지를 어떻게 해야 덜 소비할 수 있을지
목적에 따른 OS
- 일반적인 용도의 OS: 윈도우, 안드로이드 , ios 등 사용 환경을 특정할 수 없음. 따라서 여러 특성들을 모두 만족시켜야하며 Trade off 때문에 설계하기 더 까다로움.
- 특수한 용도의 OS: 원자력 발전소(Real-time, integrity), 군용 무기(Robustness, usablility, stability) 등. 요구 특성이 존재하며 이를 만족시키면 됨. 따라서 설계가 비교적 간단함.
Trade-off
동시에 달성할 수 없는 목적 사이에서 균형을 취하는 일. OS가 담당함.
OS 디자인 원칙
- Policy (정책): 환경마다 다름. 설계를 위한 것. 무엇이 되게 할건지?
- Mechanism (기법): 구현을 위한 것. policy를 달성하는 방식임. 무엇을 어떻게 할건지?
Layering (수직) VS Modularity (수평)
Layering: 설계의 복잡도를 낮추기 위해 계층별로 인터페이스 및 기능을 정의함. 복잡도는 낮아지지만 overhead가 발생함. 각 layer은 인접한 layer와만 통신함.
Module: Layering과 비슷하나 수평으로 나뉨. 다른 layer들과 독립적임. OS와 같은 큰 프로그램은 Layering, Module 둘 다 사용하기도 함.
3-3. Kernel 구조
system call
- 시스템(OS)를 부르는 것.
- 커널 모드로 진입하는 통로이며 커널의 protected 서비스를 사용하기 위함. 유저모드에서 못하는 일을 대신 해줌.
- 유저 프로그램은 직접 시스템 콜을 이용하기보다는 high-level API를 사용함.
- user application에서 C 라이브러리를 통해 시스템 콜 호출 -> CPU가 이를 알아채고 user mode에서 kernel mode로 변경 -> system handler에서 해당 명령어가 있는 메모리 주소로 감 -> 명령어 수행 -> OS가 다시 user mode로 변경 -> 이후 코드 수행
- ex) printf 함수. write라는 시스템 콜을 사용했지만 standard C library에 의해 printf로 포장됨.
trap을 이용한 모드 전환
system call 발생 -> CPU가 내부의 mode bit을 11(user)에서 00(kernel)으로 변경하고 커널의 Trap handler 호출 -> Trap handler(=system call handler)가 전달된 정보에 따라 커널 내부 함수 호출 -> 작업을 종료하면 user 모드로 변경하고 다시 유저 프로세스 수행
system call 파라미터 전달
printf 같은 함수들은 인자가 있어야함. 이를 어떻게 전달해야할까?
- 레지스터 이용: 1번은 보통 시스템콜 번호가 있어 2번부터 사용. 작은 데이터일때 유리함. 빠르고 단순.
- 메모리 블록 (연속된 메모리 공간)이용: 메모리 블록에 데이터를 저장하고 레지스터에는 시작 주소만 전달. 다시 메모리로 가서 데이터를 가져와야하므로 느림. ex) 리눅스, 솔라리스 등에서 사용
- 스택을 이용: 유저 프로그램은 파라미터를 push하고 OS는 pop함.