User Operating System Interface
운영체제와 사용자가 상호작용하는 방법을 의미하며, 크게 CLI(Command Line Interface)와 GUI(Graphical User Interface)로 나뉜다.
CLI(Command Line Interface, 명령어 인터프리터)
- CLI는 사용자가 텍스트 기반 명령어를 직접 입력하여 운영체제와 상호작용하는 방식이다.
- 일부 운영체제에서는 커널에서 직접 구현되기도 하며, 일부는 시스템 프로그램을 통해 실행된다.
- 여러 개의 명령어 인터프리터가 존재하며, 이를 쉘(Shell)이라고 한다.
- 예: Base(Linux), Zsh, PowerShell(Windows)
- CLI의 주요 기능
- 사용자로부터 명령어 입력을 받음
- 입력된 명령어를 실행
GUI(Graphical User Interface, 그래픽 사용자 인터페이스)
- GUI는 아이콘, 창(Window), 메뉴(Menu), 마우스 클릭 등의 시각적 요소를 사용하여 운영체제와 상호작용하는 방식이다.
- 운영체제와의 인터페이스는 주로 마우스, 키보드, 모니터를 통해 이루어진다.
- GUI 시스템에서는 사용자가 마우스를 이용하여 파일을 열거나, 창을 이동하는 등 데스크톱 메타포어(Desktop metaphor) 기반의 환경을 제공한다.
- 대표적인 GUI 환경:
- CDE(Common Desktop Environment) : 상용 유닉스(Unix) 시스템에서 사용
- GNOME : Linux 시스템에서 사용되는 대표적인 GUI 환경
CLI와 GUI의 공존
- 많은 운영체제는 CLI와 GUI를 모두 지원하여 사용자 환경을 유연하게 제공한다.
- 예:
- Windows : 기본적으로 GUI 환경이지만, "명령 프롬프트(command shell)"를 통해 CLI 제공
- Solaris : 기본적으로 CLI 환경이지만, 필요하면 Java Desktop, KDE 같은 GUI 환경 추가 가능
- CLI는 개발자나 서버 관리자가 주로 사용하며, GUI는 일반 사용자에게 친숙한 인터페이스를 제공한다.
System Call and API
운영체제는 사용자 프로그램이 하드웨어 및 시스템 자원을 안전하게 사용할 수 있도록 시스템 호출(System Call)과 API(Application Programming Interface)를 제공한다.
System Call(시스템 호출)
- 운영체제가 제공하는 서비스에 접근하기 위한 프로그래밍 인터페이스이다.
- 사용자가 프로그램이 커널 모드에서 실행되는 OS 기능(예: 파일 읽기, 프로세스 생성 등)을 사용할 때 시스템 호출을 실행한다.
- 대부분 C 또는 C++로 작성된다.
API(Application Programming Interface, 응용 프로그램 인터페이스)
- 애플리케이션 개발자가 사용할 수 있도록 제공되는 함수의 집합이다.
- 대부분의 프로그램은 시스템 호출을 직접 사용하는 대신 API를 통해 시스템 콜을 간접적으로 사용한다.
- 운영체제 위에서 동작하는 미들웨어 계층이 API를 제공하는 경우도 많다.
API vs System Call
- 애플리케이션은 주로 API를 사용하며, 시스템 콜을 직접 호출하지 않는다.
- API는 시스템 콜을 감싸서 제공하는 더 쉬운 인터페이스 역할을 한다.
- 예:
- Windows : Win32 API
- POSIX 기반(UNIX, Linux, Max OS X) : POSIX API
- Java : Java API(JVM용)
API를 사용하는 이유
- 호환성(Compatibility)
- 동일한 API를 지원하는 시스템에서는 같은 프로그램이 수정 없이 실행될 수 있다.
- 예를 들어, POSIX API를 사용하면 리눅스, macOS, 일부 UNIX 계열에서 동일한 코드를 실행 가능하다.
- 정보 은닉(Information Hiding)
- 시스템 콜은 복잡하고 세부적인 작업이 많기 때문에, API를 사용하면 이를 쉽게 감출 수 있다.
- 예를 들어, printf() 같은 C의 표준 입출력 함수는 내부적으로 여러 개의 시스템 콜을 수행하지만, 개발자는 간단하게 사용 가능하다.

- 대부분의 애플리케이션은 직접 시스템 콜을 사용하지 않고, API를 통해 운영체제의 기능을 활용한다.
System Call Implementation(시스템 콜 구현)
시스템 콜은 사용자 프로그램이 운영체제의 서비스(파일 입출력, 프로세스 생성, 메모리 관리 등)를 요청할 때 사용된다. 운영체제에서 커널(Kernel)이 직접 처리하는 기능이므로, 시스템 콜을 통해 사용자 프로그램이 커널 기능을 사용할 수 있다.
sys_call_table
-
각 시스템 콜은 고유한 번호(System Call Number)를 가진다.
-
운영체제는 시스템 콜을 sys_call_table이라는 메모리 내 테이블에서 관리한다.
ENTRY(sys_call_table)
.long sys_restart_syscall
.long sys_exit
.long sys_fork
.long sys_read
.long sys_write
.long sys_open
...
.long sys_foo
-
컴퓨터 부팅 시 sys_call_table이 메모리 상에 생성된다.
#define __NR_restart_syscall 0
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4
#define __NR_open 5
...
#define __NR_mq_unlink 278
#define __NR_mq_timedsend 279
#define __NR_mq_timedreceive 280
#define __NR_mq_notify 281
#define __NR_mq_getsetattr 282
#define __NR_foo 283
-
__NR_read는 시스템 콜 번호 3에 매핑된다.
-
사용자가 read()를 호출하면, 커널은 sys_call_table[3]을 찾아 sys_read함수를 실행한다.
-
Case : Linux
-
system call
int read(int fd, void* pBuf, int nBytes);
-
System call is defined as a macro
#define __NR_read
_syscall3(int, __NR_read, int, fd, void*, pBuf, int, nBytes);
System Call Parameter Passing(시스템 콜 매개변수 전달 방식)
운영체제는 사용자 프로그램이 시스템 콜을 할 애 전달한 매개변수를 받는 방법이 필요하다. 일반적으로 세 가지 방식이 존재한다.
- **X** : 블록(테이블)의 시작 위치
- CPU 레지스터 하나에 블록의 시작 위치를 저장하여 매개 변수를 전달
Linux System Call
시스템 콜 실행 과정

1. 사용자 프로그램에서 API 호출
- int read(int fd, void* pBuf, int nBytes);
2. API 내부에서 시스템 콜 번호 설정
- #define __NR_read 3
- CPU 레지스터 EAX에 시스템 콜 번호 저장(3번)
3. 소프트웨어 인터럽트(TRAP)발생
- Linux x86에서는 int 0x80 명령어를 사용하여 커널 모드로 전환
- int 0x80 : interrupt 0x80 : "소프트웨어 인터럽트"(Exception) TRAP은 User mode에서 kernel mode 진입을 위해 사용한다.
- EAX 레지스터에 시스템 콜 번호 저장
Systems Programs(시스템 프로그램)
운영체제가 기본적으로 제공하는 시스템 프로그램으로, 개발과 운영을 돕는 기능을 포함한다.
시스템 프로그램의 역할
- 파일 관리(File Management)
- 파일 및 디렉터리 생성, 삭제, 복사, 이름 변경 등
- 상태 정보 조회(Status Information)
- 시스템 상태(시간, 메모리 사용량, CPU 정보) 출력
- 프로그래밍 언어 지원(Programming Loading & Execution)
- 프로그램 실행 및 로딩(Program Loading & Execution)
- 통신 기능(Communication)
OS 구조(OS Architecture)
Monolithic Structure(단일 구조)

- OS의 모든 기능이 하나의 커널에 포함된 구조
- 예: MS-DOS
- 장점 : 빠른 속도(함수 호출이 직접 수행됨)
- 단점 : 시스템 전체가 하나의 모듈로 구성되어 확장성과 안전성이 낮음
Layered Approach(계층 구조)

-
운영체제를 여러 계층(Layer)으로 나누어 설계
-
각 계층은 하위 계층의 기능만 사용 가능(Down Call)
-
장점 : 디버깅과 유지보수가 용이
-
단점 : 계층을 명확하게 구분하기 어려움, 성능 오버헤드 발생
-
예: UNIX

Microkernel Structure(마이크로 커널 구조)

- 커널에서 필수 기능만 남기고, 나머지는 사용자 공간에서 실행
- 모든 기능이 메세지(Message Passing)로 통신
- 장점:
- 확장성이 좋음(새 기능 추가 용이)
- 안전성이 높음(커널 크기가 작아 충돌 확률이 낮음)
- 보안성 우수(프로세스 간 메모리 격리)
- 단점:
- 사용자 공간과 커널 공간 간의 통신 비용이 크므로 성능 저하
- 예: macOS, QNX
Modular Structure(모듈 구조)

- 커널을 여러 개의 독립적인 모듈(Module)로 나누고, 필요할 때 동적으로 로드/언로드 가능
- 장점:
- 불필요한 기능을 제거하여 최적화 가능
- 특정 기능을 쉽게 추가 및 수정할 수 있음
- 단점:
- 모듈 간 의존성이 발생할 경우, 충돌이 발생할 가능성이 있음
- 예: Linux Kernel
현대 운영체제 사례

- Windows, Linux, FreeBSD : 모듈형 구조 기반
- macOS, QNX : 마이크로커널 기반
- Solaris : 모듈형 커널을 지원하여 부팅 시 필요 모듈을 로드
Virtual Machines(가상 머신)
- 가상 머신(Virtual Machine, VM)은 계층적 접근 방식을 극대화한 개념으로, 하드웨어와 운영체제 커널을 마치 하나의 하드웨어처럼 취급한다.
- 가상 머신은 기본 하드웨어와 동일한 인터페이스를 제공한다.
- 운영 체제는 각 프로세스가 독립적인 프로세서와 (가상) 메모리를 갖고 실행되는 것처럼 보이도록 한다.
가상 머신의 특징
- 가상 머신 개념은 시스템 리소스를 완전히 보호하는데 효과적이며, 각각의 가상 머신은 다른 가상 머신과 완전히 분리된다.
- 하지만 이러한 완전한 격리로 인해 직접적인 리소스 공유는 불가능하다.
- 운영 체제 연구 및 개발에 적합한 환경을 제공하며, 개발을 물리적 머신이 아닌 가상 머신에서 진행함으로써 기존 시스템을 방해하지 않는다.
- 기본 하드웨어를 완벽하게 복제해야 하기 때문에 구현이 어렵고 많은 노력이 필요하다.
VMware Architecture
- VMware는 가상 머신을 실행하는 대표적인 소프트웨어로, 하드웨어를 가상화하여 여러 운영 체제가 동시에 실행될 수 있도록 한다.

Java Virtual Machine, JVM)
- 자바 프로그램은 운영 체제에 종속되지 않도록 바이트 코드(bytecode)로 변환되어 JVM에서 실행된다.
- JVM은 하드웨어가 아닌 소프트웨어 기반의 가상 머신이며, 플랫폼 독립적인 실행 환경을 제공한다.
시스템 부팅(System Boot)

- Case:Linux
- LILO(Linux Loader) : 리눅스를 위한 범용 부트 로더
- MBR 또는 특정 파티션의 부트 섹터에 설치 가능하다.
- 특정 파일 시스템에 종속되지 않는다.
- 플로피 디스크와 하드 디스크에서 운영 체제(예: 리눅스 커널 이미지)를 부팅 가능하다.