[운영체제] 2. Operating-System Structures

Operating System 서비스
- 프로그램 실행 환경 및 유저에게 서비스를 제공
- 다양한 스타일의 User Interface를 제공하여 쉽게 사용할 수 있도록 함
- Command-Line(CLI)
- Graphics User Interface(GUI) → 일반 사용자도 접근 쉬움
- touch-screen
- 프로그램 작성, 디버깅, 컴파일, 메모리에 로딩 등과 같은 일련의 과정을 제공하여 Program excution
- UI, 하드디스크, 네트워크 등 IO operation 제공
- 모바일에서 센서를 통해 물리 시스템을 제어하거나 IoT와 같은 것도 IO operation
- 파일 시스템 관리 (파일 읽기, 쓰기, 찾기, 권한 등)
- 프로세스간의 정보 교환, 네트워크, shared memory 등의 ommunications
- 하드웨어/소프트웨어 적인 에러, 외부 접근 등의 Error detection
- 다수의 유저 또는 job이 실행될 때 각각 알맞게 리소스 할당 ⭐
- 주요 자원: CPU cycles, main memory, file storage, IO system
- 자원 관리가 운영체제의 kernel
- OS가 실행되면서 누가, 언제, 어떤 리소스를 사용했는지, 어떤 에러가 발생했는지 등 이벤트에 대한 logging
- 리소스에 대한 권한(protection), 외부 공격으로 부터 보호(security)

- 가장 밑에 하드웨어
- OS안에 다양한 서비스, system calls, UI
User Operating System Interface
- CLI (command line interpreter, shell)
- 사용자가 명령어를 직접 입력
- 어떤 명령어가 있는지 알아야 함
- 개발의 편리함, 정교하고 빠르게 명령어 입력 가능
- GUI
- 일반 사용자가 쉽게 사용할 수 있는 desktop metaphor interface
- 파일, 프로그램, 액션을 나타내는 아이콘
- 보통 CLI도 같이 사용할 수 있음 (UNIX나 LINUX는 CLI기반인데 GUI를 제공하는 편)
- Touchscreen
- 모바일, 스마트폰, 직관적
- virtual keyboard, voice command
System calls
- 다양한 application이나 시스템 프로그램이 공통으로 필요한 기능을 OS에서 미리 구현해 둠
- system call보다 좀 더 확장한게 API (Application Porgramming Interface)
- 다양한 라이브러리나 미들웨어 기능을 쉽게 사용할 수 있도록 제공하는 API기능
- OS를 포함해서 시스템 소프트웨어(미들웨어, 데이터베이스, 라이브러리 등)에서 application을 쉽게 작성할 수 있도록 함
- 세가지 주 API는 Win32 API, POSIZ API(for unix, linux), Java API
- System call example (file copy) → 여러가지 System call로 이뤄짐
- input 파일 이름 요청 (어떤 파일을 copy할건지)
- 화면에 띄워서 사용자가 입력
- output 파일 이름 요청
- 화면에 띄워서 사용자가 입력
- input 파일을 열기 (근데 그 파일이 없으면 err)
- output 파일 생성 (기존에 그 파일이 있었으면 err)
- input파일에서 한줄씩 읽고 output파일에 한줄씩 쓰기 → 읽을게 없을 때까지 반복
- output 파일 닫기
- 완료 메세지 화면에 띄우기

- Standard API example (file read)

System call Implementation
- index table로 system call 종류를 구별한다 (system call interface)
- system call 실행은 kernel이 알아야한다
- application
main()에서 system call 함수 호출
- user mode에서 kernel mode로 trap (software interrupt)
- kernel은 system call interface를 통해 해당 system call의 index 파악
- kernel이 해당 system call이 있는 주소를 통해 system call 실행
- 완료 시 user에게 return
System call parameter passing
- 일반적인 function call은 stack을 통해 넘김
- 근데 user와 kernel mode는 각자 다른 stack을 가짐
- 그래서 parameter를 register를 통해 전달 (빠르게 전달 가능)
- but 사이즈 한계가 있으므로, user와 kernel이 공유할 수 있는 공간에 parameter를 넣고, 해당 주소를 register로 전달할 수도 있음 (linux, solaris)

System call Types
- process control
- 프로세스 생성, 종료, 로드, 실행
- event(interrupt)
- 메모리 할당
- debugger
- locking (여러 프로세스가 같은 리소스에 접근할 때 충돌이 발생하지 않도록)
- File management
- 파일 생성, 제거, 읽고, 쓰고, 열고, 닫고..
- 파일 속성 읽고 쓰기
- Device management
- Information maintenance
- 시간, 날짜, 파일, 디바이스 등과 같은 시스템 정보
- Communications
- communication port 생성, 제거, port를 통해 메세지를 받고 보내고
- shared-memory model: 여러 프로세스가 한 메모리를 통해 데이터 공유
- messeage passing mode: 프로세스 간에 실제로 데이터를 주고받으며 공유
- Protection
- 리소스에 대한 권한


- EX: Arduino
- OS범주에 속하지 않고, 단순히 센서로부터 데이터를 읽어들이고 컨트롤러를 제어하는 프로그램(Sketch)
- single-task

- EX: FreeBSD
- unix의 일종
- multitasking가능 (multiprocessor)
- 새로운 프로세스 생성
fork() 로 부모 프로세스를 복제하여 자식 프로세스 생성
- 만약 자식 프로세스가 부모와 다른 일을 하고싶다면
excute() 를 통해 실행
System services
- system call을 포함해서 더 많은 서비스를 제공
- ex) 드래그하여 파일 copy → 여러 system call을 사용하여 용이한 서비스 제공
- 파일 관리
- 시스템에 대한 다양한 상태 모니터링 (status information)
- date, time, memory, disk, user, file…
- 파일 수정
- text editor와 같은 system software 사용
- Application에서 system call로 직접 OS에 접근하여 수정할 수도 있지만
- system software를 거쳐가며 더 편하게 수정 가능
- 다양한 컴퓨팅 언어로 소프트웨어를 제작, 컴파일, 로딩, 실행
- 다양한 communication 메카니즘, 통신 API를 제공 → 프로그래머가 쉽게 작성
- Background services
- 메모리 관리, 인터넷 접속 처리, 로깅 모니터링
- OS가 부팅될 때(초기화될 때) 만들어짐
- services, subsystems, daemons
- Application Program을 작성, 컴파일, 로딩 등
Linkers and Loaders
- 소스코드를 컴파일하면 object file이 됨
- 기능별로 독립적인 object file들이 생성되고, linker가 object file들을 연결하여 excutable file을 만듦
- loader가 excutable file을 메모리에 올려 프로그램 실행
- static loader: 정해진 자리에 로딩
- Relocation loader: 로딩 위치가 매번 다름 (메모리의 빈 자리를 차지)
- Dynamic link loader(dll): 프로그램의 모든 부분을 한번에 로드하는게 아니라, 해당 라이브러리 함수가 호출될 때 로드
- 전체적인 흐름
- 소스코드 작성
main.c
- 컴파일러에 의해 obj file로 만들어짐
main.o
- linker가 obj file들을 연결해서 executable file 생성
main.exe
- excutable file을 실행하면 loader가 메모리에 로드하면서 프로그램이 실행됨 (dynamically linked libraries)

Operating System Specific
- 운영체제마다 System call이 다름 (OS dependency)
- Virtual machine을 사용하여 보완
- ex) VM을 포함하는 java는 다양한 OS에서 실행될 수 있음
- 소프트웨어의 호환성을 위해
- Application Binary Interface (ABI)
- obj레벨의 인터페이스
- OS나 하드웨어에 상관없이 공통으로 호환
Operating System Design and Implementation
- 사용자 목표: OS가 편리해야함, 잘 안죽어야함, 안정적, 빠른 반응
- 시스템 목표: 사용자 목표 달성을 위해 공정하게, 여러 사용자에게 동시에 확장성있게 제공할 것인가
- 중요 원리
- Policy: 무엇을 할건지 (정책)
- Mechanism: 어떻게 할건지 (구체적 알고리즘)
- Implementation
- 다양한 언어로 운영체제 작성
- 초반에는 어셈블리어로 작성됐고, 요즘은 호환성을 위해 C나 C++로 작성됨
- IO 디바이스의 low-level 컨트롤을 위해 일부가 어셈블리어로 작성되기도 함
- high-level language로 작성하면 하드웨어에 port가 필요하고 느림
- 하드웨어가 달라서 동작이 안될 때, Emulation으로 해당 하드웨어에 알맞게 application program을 변환해주는?
Operating System Structure
- 다양한 형태의 OS
- MS-DOS: 초기, 간단
- Unix: 단일 체제 OS, 성능은 좋지만 유연성이 떨어짐
- layered architecture: 계층별 체제로 위의 단점 보완
- Module 구조: 모듈별로 프로그램을 OS에 쉽게 붙일 수 있음 (OOP 개념)
- Microkernel 구조: 커널을 작게, 유연성, 안정성
Monolithic Structure (단일운영체제구조)
- OS전체가 한 덩어리 (계층X, 모듈X)
- 속도가 빠르다
- 모든 OS기능이 physical hardware interface
- 하드웨어 리소스 관리
- 초기 unix, 약간의 계층구조를 가지지만 완벽하지않음
- Hardware Abstraction Layer: 다양한 하드웨어를 일반화, OS는 하드웨어별로 고려할 필요X
- OS 기능: CPU scheduling, 메모리 관리(페이지 단위로), demand paging, virtual memory

Linux System Structure
- unix type OS
- Monolithic + modular design → 유연성 향상
- kernel이 module로 구성

Layered Approach
- 얘도 Monolithic의 단점인 유연성 부족을 보완
- 위에 있는 레이어는 아래 레이어의 서비스(function call)를 받음
- 해당 레이어를 원하는대로 수정 가능

Microkernels
- OS의 최소한의 핵심 기능은 kernel에 남겨두고, 나머지는 user program처럼 동작(서버로)
- 서버를 통해 작동하기 때문에 확장이 용이
- 한 기능이 문제가 생겨도 영향을 받지 않는다 (원래 OS는 하나로 뭉쳐있으니까, 어디서 문제가 발생하면 전체가 고장남) → 신뢰성, 안정성
- but, 서버를 통해 작동하기 때문에 느린 속도 (performance overhead)
- ex) Mach OS (Mac OS X kernel이 Mach을 기반으로 만듦)

- 위 이미지에서 file system이랑 device driver가 kernel이 아닌 user mode로 갔지만 어쨌든 OS다!!!! 그냥 application program처럼 user mode에서 동작할 뿐
Modules
- 객체지향 방식으로 접근하여 OS를 모듈로 구성
- OS에 모듈을 추가하거나 제거하기가 쉬워 유연성 증가
- ex) Linux, Solaris
Hybrid Operating System
- 다양한 OS 구조를 채택 (각각 장단점이 확실함)
- 위에 나왔 듯, Linux와 Solaris는 Monolithic+modular
- Window는 주로 Monolithic인데 부분적으로 microkernel
- Max OS X는 다윈 운영체제(mack기반→ microkernel)+ Unix(monolithic) 같이 채택
macOS and IOS
- 아래는 Darwin OS

Android
- Linux kernel 기반
- 저전력, 저사양에 맞춰 power management 기능 추가

Building and Booting an Operating System
- 운영체제 설계 구조에 따라 소스코드 작성
- 운영체제 Configuration잡기 (메모리 크기, CPU종류, 디바이스 종류 등)
- 소스코드 컴파일
- 운영체제 설치
- 운영체제를 메모리에 로딩 후 실행 → Booting
- ex) Linux
1. Linux 소스코드 다운로드
2. configuration 잡은 후 컴파일
3. 컴파일할 때, kernel image를 생성 (application에서 excutable file 처럼)
4. kernel에 다양한 모듈을 만들기
5. 새로운 kernel을 시스템에 install
System Boot
- 부팅프로그램(bootstrap loader)은 컴퓨터를 꺼도 유지되도록 비휘발성인 ROM이나 EEPROM에 위치
- bootstrap loader가 운영체제를 올림
- but, 운영체제가 크고 로딩이 복잡해서 ROM에 다 넣긴 무리
- 그래서 보통 Bootstrap이 Boot block을 올리고, 하드디스크에 있는 boot block이 운영체제를 올림 → 2step으로 ROM 공간 절약 및 운영체제 종류 선택 부팅이 가능해서 유연성 증가
Operating System Debugging
- 어쨌든 OS도 소프트웨어이기 때문에 디버깅 필요
- OS의 다양한 configuration값을 조정하며 performance tuning
- 작업관리자로 CPU상태, 메모리, disk 등의 하드웨어 리소스가 어떻게 사용되는지 파악 가능
- log file을 사용하여 trace (프로그램의 흐름 추적)
- core dump: Application 에러 발생 시, 프로세스의 메모리를 캡쳐한 파일 생성
- crash dump: OS 에러 발생 시, kernel 메모리를 포함한 파일 생성
- BCC (BPF Compiler Collection)
- Linux의 trace toolkit
- ex) disk 성능, 접근 시간, 읽기인지 쓰기인지, 크기, 접근 latancy time, 리소스 사용 이력 등 측정 가능
- 다양한 OS 기능별로 전담 tracing 툴을 가짐
