Search

Operating System Structure

운영체제가 제공하는 서비스

종류

1.
파일 시스템
2.
I/O 수행
3.
하드웨어 리소스 할당: CPU 자원을 효율적이고 공평하게 사용하도록 스케줄링.
4.
유저 인터페이스:
CLI는 텍스트 기반으로 쉘에서 명령을 내릴 수 있도록 한 것. 깜빡거리는 것을 프롬프트라고 하며, 쉘이라고 이름 붙인 이유는 사용자가 세부적인 동작을 알 필요 없도록 껍데기로 감싸서 abstraction했다는 뜻이다. Bourne Shell, Bash가 대표적이다. Bash는 "born again shell"의 약자이다.
GUI(Graphic User Interface)는 그래픽 UI를 통해 더 쉽게 사용할 수 있게 한 것. Mac OS X, 아이폰 터치스크린 인터페이스 등이 있다.
5.
Communication: 프로세스 사이가 격리되어 있고 직접적으로 데이터를 주고받을 수 없다. 서로 데이터를 주고받으려면 운영체제의 허락을 받아야 한다. IPC(Interprocess Communication)라고 부른다.
6.
Protection 및 보안
7.
계정 관리
8.
프로그램 실행 등

시스템 프로그램

1.
정의: 프로그램 개발과 실행을 편하게 해주는 개발 환경. 시스템 유틸리티라고도 한다.
2.
프로그래밍 언어 지원, 로드 및 실행 프로그램:
컴파일러: 광의의 컴파일러는 전처리기와 translator로 이루어져 있다. #include, #define 등의 전처리 지시문을 통해서 코드가 있는 걸로 가정을 하고 컴파일할 수 있도록 해준다. 실제 코드는 라이브러리에 존재한다. 소스코드를 컴파일하면 목적코드가 생성된다. 리눅스는 gcc가 기본으로 탑재되어 있으나 윈도우는 별도로 다운로드받아야 한다.
링커: 컴파일이 끝나면 목적 파일이 소스코드 갯수만큼 나오는데, 목적 파일들을 묶어주는 것이 링커이다. 링킹을 하는 방식은 Static Linking과 Dynamic Linking으로 나뉜다. 일반적으로 Dynamic Linking을 많이 쓴다. Dynamic Linking은 예를 들어 cout을 하는 코드가 있으면 해당 기능이 있는 라이브러리로 jump해서 수행하고 돌아오는 방식이다. Static Linking의 경우 코드 안에 cout 코드를 다 복사 붙여넣기 하여 결과적으로 바이너리 파일의 사이즈가 커진다. Static Linking을 많이 사용하는 분야는 임베디드이다. 공용 라이브러리의 사이즈가 커서 사용하는 부분만 복사 붙여넣기 한 다음 바이너리로 만드는 것이다. 공용 라이브러리는 윈도우에서는 .dll (dynamically linked library)이고 리눅스에서는 .sa.so 파일이다.
로더: 실행 파일을 실행했을 때 디스크에서 메모리로 올려주는 로딩을 수행한다.
파일 변경 프로그램: Windows의 Notepad, 리눅스의 vi 등의 텍스트 에디터.
통신: email 등의 통신 관련 서비스 제공.
상태 정보: 시스템 날짜, 사용 가능한 메모리, 디스크 공간 등의 시스템 정보 제공.
파일 관리: ls, cd, rm, mv 등의 명령어도 프로그램으로 구현되어 터미널에서 파일을 관리할 수 있도록 해주는 시스템 프로그램이다.

System Call 서비스

1.
순서: Dual mode operator로 구현되어 있으며 user mode와 kernel mode로 나뉜다. user mode에서 read()와 같은 시스템 콜을 호출해서 trap이 걸리면 kernel mode로 변경되어 프로세스 상태를 저장하고 trap handler가 동작한다. trap handler가 벡터 테이블에서 read()의 핸들러를 찾아 커널에서 수행 후 프로세스에 결과를 돌려주고 user mode로 돌아간다.
2.
시스템 콜은 함수 형태로 구현되어 있고 코드의 주소값을 알아야 해당하는 함수로 점프해 수행할 수 있다. 프로세스는 함수들의 주소를 벡터 테이블로 관리한다. 이를 시스템 콜 테이블이라고 한다. 시스템 콜의 input parameter는 레지스터를 통해서 넘겨준다. 예를 들어 printf() 같은 함수를 수행하면 printf() 함수는 stdio 라이브러리에 구현되어 있고, printf() 함수의 내부에는 write() 시스템 콜이 있다. 시스템 콜이 호출되면 인터럽트가 발생하고 커널이 CPU에 올라온다 (kernel mode가 된다). 트랩 핸들러는 레지스터에서 인덱스를 찾아 시스템 콜 테이블에서 인덱스의 값(주소)이 가리키는 시스템 함수를 실행한다. 작업이 끝나면 유저 모드로 되돌아간다. 이러한 과정이 내부에서 시스템으로 구현되어 있는 것이고, 우리가 직접 시스템 콜을 호출하는 경우는 애플리케이션 개발 레벨에서는 거의 없다.
3.
시스템 콜 standard API를 보면 상세하게 시스템 콜에 대해 파악할 수 있다. read()는 파라미터 중 하나로 fd를 받는데, 파일 디스크립터라는 뜻이다. 파일 디스크립터는 프로세스에서 다른 파일을 정수값으로 매치해서 관리하는 테이블이다. 리눅스에서 파일 디스크립터 0, 1, 2번은 지정이 되어 있는데, 0번은 표준 입력 (stdin), 1번은 표준 출력 (stdout), 2번은 표준 에러 (stderr)이다. 유닉스 운영체제에서는 대부분의 요소가 파일처럼 취급된다. 디렉토리, 하드웨어 장치 등도 특수한 종류의 파일로 취급된다. 키보드 같은 입력 장치는 /dev 디렉토리에 있는 특수한 파일로 취급된다. 키보드를 타이핑할 시 /dev 디렉토리에 있는 파일에 데이터가 쓰여진다.
4.
유닉스 계열과 윈도우의 시스템 콜은 형태가 다르다. 유닉스 계열의 운영체제들은 POSIX 표준에 따라서 만들어지기 때문에 시스템 콜의 형태가 같다. 윈도우는 스레드의 개념이 나오고 난 후 생긴 운영체제라서 시스템 콜이 다르고 호환성 문제가 있다.
5.
유닉스 시스템 콜 예시:
Process Control: fork(), exit(), wait()
파일 조작: open(), read(), write(), close()
디바이스 조작, Protection 등

OS 구조

Monolithic 커널

1.
정의: 운영체제가 가져야 하는 모든 기능을 한 덩어리로 구현한 커널이다.
2.
모놀리식 커널은 아주 복잡한 구조가 한 덩어리로 되어 있기 때문에 소프트웨어 엔지니어링 이슈가 발생할 수 있다(유지보수가 어렵다). 각각의 기능들 간의 의존성이 높기 때문에 하나를 고치면 다른 여러 개를 더 고쳐야 하는 상황이 발생한다. 또한 모놀리식 커널은 이미지의 크기가 커서 하드웨어에 제약이 있다. 하지만 시스템 콜이 발생할 경우 커널에서 한 번에 처리가 가능하기 때문에 오버헤드가 적다.

마이크로커널

1.
정의: 필수적으로 필요한 기능만 커널 형태로 구현하고 그 이외의 기능들은 어플리케이션 형태로 만들어서 붙인다. 필수적인 기능만 커널에 넣고 나머지는 다른 어플리케이션보다 높은 권한을 가진 어플리케이션으로 동작하게 만드는 것이다. 마이크로커널이라 이름 붙인 이유는 최소한의 필수 기능만 붙여서 만든 작은 커널이기 때문이다.
2.
파일 시스템, 디바이스 드라이버 등을 유저 모드에서 동작하도록 함으로써 커널에 들어가는 기능을 최소화한다.
3.
마이크로커널은 오버헤드가 많이 발생하는 문제가 있다. 예를 들면 어플리케이션이 파일 I/O를 요청하면 커널 모드로 가서 파일 시스템에 메시지를 전달하고 파일 시스템의 메시지를 커널 모드로 다시 돌아가서 디바이스에 요청하고, 다시 커널 모드로 돌아갔다가 파일 시스템에 메시지를 전해주고… 복잡한 과정을 거친다. 모놀리식 커널에서는 커널 모드에 들어가서 한 번에 해결될 문제들을 여러 번에 걸쳐서 해결하게 되고, 또한 어플리케이션 간 메시지를 주고받기 위해서 커널이 필요하기 때문에 시스템 콜이 더 많아져서 오버헤드가 많이 발생한다.

레이어드 어프로치

1.
정의: 레이어 간의 dependency가 없도록 레이어를 두고 운영체제를 만드는 개념이다. 하지만 개념만 존재하고 실제로 이것에 입각해서 만들어진 운영체제는 존재하지 않는다.

모듈러 어프로치

1.
정의: 커널 일부분을 모듈로 만들고 코어로 연결하는 형태. 운영체제를 설치하는 과정에서 필요한 이미지를 모아서 모놀리식 형태로(하나로 이루어진 커널로) 설치하는 것이다.
2.
리눅스와 솔라리스가 모듈러 어프로치 방식으로 구현되어 있다. 모듈은 상호 간 의존성이 없거나 낮기 때문에 유지보수가 편하다. 또한 필요한 것만 붙여서 커널을 만들기 때문에 이미지의 크기도 작아져 부팅 과정의 로딩도 빨라지고 메모리 용량도 적게 차지한다.
3.
LKM (Loadable Kernel Module): 각각의 모듈들을 LKM이라고 한다. 적재 가능한 커널 모듈로, 실행 중인 커널을 확장하는 코드를 포함하는 목적 파일이다. 새로운 하드웨어(디바이스 드라이버) 지원이나 시스템 콜 추가하기 위해서 로드하여 커널 기능을 확장한다.

하이브리드 어프로치

1.
정의: MacOS X, iOS, 안드로이드 등이 해당한다. 안드로이드는 운영체제라기보다 플랫폼 혹은 프레임워크이다. 리눅스 커널을 기반으로 동작하면서 그 위에 여러 가지 시스템 프로그램을 포함한 형태이다. 임베디드 리눅스에 서비스를 올려서 만든 플랫폼이다.