Post

[OS] 시스템 콜과 OS 구조

운영체제가 제공하는 서비스, 시스템 콜의 개념과 동작 원리, OS 구조의 발전 과정, 가상 머신과 JVM에 대해 정리한 글입니다.

[OS] 시스템 콜과 OS 구조

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

  • 유저 인터페이스(UI):
    • CLI(Command Line Interface):
      • 명령어를 직접 입력하는 방식
      • 유닉스·리눅스·macOS 하단(유닉스 커널 기반)에서 디폴트로 제공
    • GUI(Graphical User Interface):
      • 마우스와 아이콘 기반의 시각적 환경
      • Windows·macOS에서 디폴트
    • 배치(Batch): 프로그램과 데이터를 미리 제공하면 사용자 개입 없이 자동 실행 (예: 야간 백업, 월급 계산)
  • 프로그램 실행(Program Execution): 프로그램을 메모리에 로드 → 실행 → 정상/비정상 종료까지 관리
  • 입출력 서비스(I/O Operations): 파일 또는 특정 I/O 디바이스에 대한 읽기·쓰기 요청 처리
  • 파일 시스템 조작(File System Manipulation): 파일 생성·삭제·읽기·쓰기·목록 나열·정렬 등 파일 관리 전반
  • 프로세스 간 통신(Communication)
    • 공유 메모리(Shared Memory): 프로세스들이 공통 메모리 공간에 쓰고 읽는 방식
    • 메시지 패싱(Message Passing): 정해진 포맷(발신자, 내용, 크기 제한 등)에 맞춰 메시지를 주고받는 방식
  • 오류 감지(Error Detection): 하드웨어 오류는 인터럽트(Interrupt)로, 소프트웨어 오류는 트랩(Trap)으로 감지. 디버깅 도구도 서비스에 포함
  • 시스템 효율을 위한 서비스 (3가지):
    • 자원 할당(Resource Allocation): CPU, 메모리, 버스 사이클 등 자원의 할당 및 회수
    • 어카운팅(Accounting):
      • 사용자별 자원 사용량 기록 → 시스템 업그레이드 계획 수립에 활용 (예: 메모리 사용률 80% → 메모리 우선 업그레이드)
      • 과거에는 과금 목적으로도 사용
    • 보호 및 보안(Protection & Security):
      • 자원 접근 통제(Protection) + 외부 공격 방어(Security)
      • 인증(Authentication)이 기본 수단

2. 사용자 인터페이스 심화: CLI vs GUI

CLI와 GUI는 운영체제 서비스에 접근하는 두 가지 대표적 방식이며, 현대 운영체제는 대부분 두 방식을 모두 제공한다. 차이는 어느 것이 기본값이냐에 있다.

  • CLI 명령어 구현 방식 두 가지:
    • 커널 내장(Built-in) 방식:
      • 모든 명령어를 하나의 프로그램으로 컴파일하여 커널에 상주
      • 실행 속도가 빠르나 수정·추가 시 전체 재컴파일 필요
    • 시스템 프로그램 방식:
      • 각 명령어가 독립적인 프로그램 파일로 특정 디렉토리(예: /bin, /cmd)에 저장
      • 명령어 추가·수정이 용이
운영체제디폴트 UI대안 UI
WindowsGUICLI (명령 프롬프트/PowerShell)
macOSGUI터미널(CLI) - 유닉스 커널 기반
Solaris (유닉스 계열)CLIGUI 옵션

커널 내장 방식은 속도 면에서 유리하지만 유지보수가 어렵고, 시스템 프로그램 방식은 유연성이 높다는 트레이드오프가 존재한다.


3. 시스템 콜(System Call) 개념 및 동작 원리

시스템 콜 개요 - 사용자 프로그램에서 OS 서비스까지의 계층 구조 시스템 콜은 사용자 프로그램이 OS 서비스에 접근하는 유일한 공식 경로이다

시스템 콜은 운영체제가 제공하는 서비스에 접근하기 위한 프로그래밍 인터페이스로, 사용자 프로그램이 운영체제 기능을 사용할 수 있는 유일한 공식 경로이다. 실제 프로그래밍에서는 시스템 콜을 직접 호출하지 않고, 그 위에 위치한 API나 라이브러리 함수를 통해 간접적으로 호출한다.

시스템 콜은 각각 고유 번호가 부여되며, 사용자는 API를 통해 간접적으로 호출한다.

  • 계층 구조 (하위 → 상위):
    • 시스템 콜(System Call) → API(Application Programming Interface) → 라이브러리 함수(Library Function)
  • 주요 API 종류:
    • Windows: Win32 API
    • Unix/Linux: POSIX API
    • Java 가상 머신: Java API
  • 동작 과정 (예: copy 명령어):
    1. 소스 파일명 입력 수신
    2. 목적지 파일명 입력 수신
    3. 소스 파일 존재 여부 확인, 목적지 파일 중복 여부 확인 (오류 처리)
    4. 소스 파일 열기 → 내용 읽기 → 목적지 파일에 쓰기 → 루프 반복 → 완료 메시지 출력
    5. 이 모든 단계에서 다수의 시스템 콜이 사용됨
  • 시스템 콜 호출 과정 (실제로는 번호 기반):

시스템 콜 호출 과정 - 라이브러리 함수에서 시스템 콜 테이블을 통해 커널 루틴 실행 printf → write 시스템 콜 → 시스템 콜 테이블 조회 → 커널 루틴 실행

  1. 사용자 프로그램에서 라이브러리 함수(예: printf) 호출
  2. 라이브러리 함수가 필요한 시스템 콜(예: write) 호출
  3. 운영체제가 메모리 내 시스템 콜 테이블을 조회 → 해당 번호의 루틴 주소 확인
  4. 해당 주소로 이동하여 루틴 실행
  • ReadFile 함수 예시 (Win32 API):
    • 반환값: bool (True/False)
    • 파라미터: 파일 핸들, 버퍼 주소, 읽을 바이트 수, 실제 읽은 바이트 수, 오버랩 I/O 여부
  • 파라미터 전달 방식 3가지:
방식설명특징
레지스터 방식CPU 레지스터에 직접 파라미터 값 저장가장 단순하나 레지스터 개수 제한
메모리 블록 방식메모리 블록에 저장 후 시작 주소만 레지스터로 전달파라미터 수 제한 없음
스택 방식스택 영역에 파라미터를 pushLIFO 구조로 동작

4. 시스템 콜의 유형

시스템 콜은 기능에 따라 5가지 유형으로 분류되며, 각 유형 안에 다수의 세부 시스템 콜이 존재한다. 여기서 제시되는 목록은 전체의 일부이며, 실제로는 훨씬 더 많은 시스템 콜이 존재한다.

  • 프로세스 제어(Process Control):
    • end (정상 종료), abort (강제 종료)
    • load (메모리 로드), execute (실행)
    • create process (프로세스 생성), terminate process (종료)
    • get/set process attributes (속성 읽기/설정)
    • wait time (일정 시간 대기), wait event (이벤트 발생까지 대기), signal event (시그널 발생)
    • allocate memory (메모리 할당), free memory (메모리 회수)
  • 파일 관리(File Management):
    • create file, delete file
    • open, close
    • read, write, reposition (헤드 위치 재설정)
    • get/set file attributes (파일 속성 읽기/설정)
  • 디바이스 관리(Device Management):
    • request device (디바이스 요청), release device (반환)
    • read, write, reposition
    • get/set device attributes
    • logically attach/detach device (외장 디바이스 마운트/언마운트)
  • 정보 관리(Information Maintenance):
    • get/set time or date
    • get/set system data
    • get/set process, file, or device attributes
  • 통신(Communication):
    • create/delete communication connection (연결 생성/삭제)
    • send/receive messages (메시지 송수신)
    • transfer status information (상태 정보 전달)
    • attach/detach remote device (원격 디바이스 연결/해제)

5. 시스템 프로그램의 정의와 유형

시스템 프로그램은 사용자에게 직접 보이는 프로그램으로, 프로그램 개발과 실행을 위한 효율적이고 편리한 환경을 제공하는 것을 목적으로 한다. 시스템 프로그램은 내부적으로 다수의 시스템 콜을 호출하여 동작하지만, 이 시스템 콜들은 사용자에게 직접 노출되지 않는다. 시스템 프로그램은 크게 6가지 유형으로 분류된다.

  • 파일 조작(File Manipulation): 파일의 생성, 삭제, 복사, 이름 변경, 출력 등 파일 관리 기능을 수행하며, 일반적으로 파일 관리자(파일 탐색기)가 이에 해당한다.
  • 상태 정보(Status Information): 현재 날짜·시간, 사용 가능한 메모리·디스크 용량, 현재 로그인된 사용자 수, CPU 및 메모리 이용률, 로그·디버깅 정보 등을 수집하여 정해진 포맷으로 모니터 또는 프린터를 통해 사용자에게 제공한다.
  • 레지스트리(Registry): 시스템 정보를 저장하고 지속적으로 업데이트하는 저장소로, 수백 개의 레지스터들의 집합으로 구성된다.
  • 파일 수정(File Modification): 텍스트 에디터를 이용한 프로그램 작성, 수정, 내용 검색 기능을 제공한다.
  • 프로그램 언어 지원(Programming Language Support): 컴파일러, 어셈블러, 인터프리터 등을 포함하며, 고급 언어로 작성된 프로그램을 기계어로 번역한다.
  • 프로그램 로딩 및 실행(Program Loading and Execution): 로더, 링키지 에디터, 오버레이 로더, 디버거 등을 포함한다.
  • 통신(Communication): 프로세스 간 통신, 사용자 간 통신, 원격 컴퓨터 시스템 간 통신을 지원하며, 웹 브라우저, 이메일, 원격 로그인 소프트웨어, 파일 전송 도구 등이 이에 속한다.

6. 컴파일러와 인터프리터, 로더 및 링키지 에디터

컴파일러, 인터프리터, 로더의 동작 과정 소스 코드에서 실행 파일까지의 변환 과정: 컴파일러/인터프리터, 로더, 링키지 에디터

프로그램 언어 지원 도구들은 고급 언어로 작성된 소스 코드를 컴퓨터가 이해할 수 있는 기계어로 변환하는 역할을 한다. 컴파일러와 인터프리터는 동일한 목적을 가지지만 번역 방식에서 차이가 있으며, 로더와 링키지 에디터는 프로그램을 메모리에 올리고 외부 라이브러리와 연결하는 역할을 담당한다.

도구설명예시
컴파일러(Compiler)프로그램 전체를 한꺼번에 번역C, C++
인터프리터(Interpreter)프로그램을 한 줄씩 번역하여 실행Java
  • 로더(Loader)의 종류:
    • 절대 로더(Absolute Loader): 프로그램을 고정된 메모리 위치에 적재하며, 위치가 변경되지 않는다.
    • 재배치 가능 로더(Relocatable Loader): 프로그램 실행 중 메모리 상의 위치가 변경될 수 있다.
    • 오버레이 로더(Overlay Loader): 메모리 공간이 부족할 때, 프로그램의 일부를 먼저 로딩하여 실행하고, 실행이 끝난 부분을 내려보낸 후 다음 부분을 로딩하는 방식으로 동작한다.
  • 링키지 에디터(Linkage Editor): 메인 프로그램에서 C 라이브러리 등 외부 라이브러리의 함수를 호출할 때, 해당 함수와 메인 프로그램을 연결시켜 주는 역할을 한다.
  • 디버거(Debugger): 프로그램 실행 중 발생한 오류를 쉽게 찾고 수정할 수 있도록 도와주는 도구이다.

7. 운영 체제의 설계 목표와 정책·메커니즘 분리 원칙

운영 체제의 설계와 구현에는 정해진 단계별 방법론이 존재하지 않는다. 그러나 경험적으로 가장 먼저 해야 할 일은 운영 체제가 달성해야 할 목표와 세부 규격을 명확히 정의하는 것이다. 이때 사용 환경(노트북, 서버 등)과 사용할 CPU 종류, 파일 시스템 유형 등 하드웨어 구성이 설계에 큰 영향을 미친다.

  • 사용자 목표: 사용하기 쉽고, 배우기 쉬우며, 신뢰도가 높고, 안전하고, 빠른 운영 체제.
  • 시스템 목표: 설계·구현·관리가 쉽고, 유연하며, 신뢰도가 높고, 오류가 없으며, 자원 관리 측면에서 효율적이고 공정한 운영 체제.

정책(Policy)과 메커니즘(Mechanism)의 분리: 정책은 “무엇을 할 것인가”, 메커니즘은 “어떻게 구현할 것인가”를 의미한다. 정책은 변경될 수 있으므로 메커니즘과 분리해야 최대한의 유연성을 확보할 수 있다.

  • 정책·메커니즘 혼합 시 문제 예시: 학생 실습용으로 타이머 카운터를 10비트로 설계했다가, 나중에 대형 애플리케이션을 실행해야 할 때 타이머 값이 너무 작아 프로그램이 강제 종료되는 문제가 발생할 수 있다.

8. 운영 체제 구조의 발전: MS-DOS에서 마이크로 커널까지

운영 체제의 구조는 하드웨어 자원의 제약과 소프트웨어 복잡성 증가에 따라 지속적으로 발전해 왔다. MS-DOS의 단순하고 비분리된 구조에서 시작하여, 계층적 구조, UNIX의 모놀리식 커널, 그리고 마이크로 커널 구조로 진화하였다.

  • MS-DOS 구조:
    • 초기 PC의 메모리 크기가 640KB(확장 시 최대 1MB)로 매우 제한적이었기 때문에, 디스크 중심의 운영 체제로 설계되었다.
    • 레이어 구조가 존재하기는 하지만, 메모리 제약으로 인해 애플리케이션 프로그램이나 시스템 프로그램에서 하드웨어에 직접 접근하는 경로가 존재하여 레이어 간 분리가 제대로 이루어지지 않았다.
  • 계층적 구조(Layered Approach):
    • 레이어 0(하드웨어)부터 최상위 레이어(사용자 인터페이스)까지 명확히 분리된 계층 구조를 가진다.
    • 각 레이어는 하위 레이어의 기능만 접근할 수 있으며, 상위 레이어의 기능에는 접근할 수 없다.
    • 레이어 구성 시 각 레이어에 어떤 기능을 배치할지 신중하게 결정해야 한다는 제약이 있다.
  • UNIX 구조:
    • 커널에 파일 시스템, CPU 스케줄링(잡 스케줄링), 메모리 관리(페이지 교체, 요구 페이징 등), 디스크 드라이버, 각종 I/O 관련 기능 등 매우 많은 기능이 집중되어 커널이 비대해졌다.
    • 커널 수정이나 기능 추가 시 커널 전체의 연관 부분을 모두 수정해야 하는 문제가 발생한다.
  • 마이크로 커널(Micro Kernel) 구조:
    • 커널의 핵심 기능만 최소화하여 마이크로 커널에 남기고, 나머지 기능들은 유사한 것끼리 묶어 모듈화하여 분리한다.
    • 모듈 간 통신은 마이크로 커널을 통한 메시지 패싱(Message Passing) 방식으로 이루어진다.
    • 각 모듈은 객체 지향(Object-Oriented) 방식으로 개발되며, 평상시에는 디스크에 존재하다가 필요할 때만 메모리에 로딩되고, 사용 후 다시 디스크로 내려보내는 방식으로 동작한다.

마이크로 커널의 장단점: 확장 용이, 이식(포팅) 용이, 코드 양 감소로 신뢰도 향상, 보안 강화가 장점이며, 모듈 간 메시지 패싱으로 인한 오버헤드 발생이 단점이다.

운영 체제 구조의 발전 - MS-DOS에서 마이크로 커널까지 MS-DOS의 비분리 구조에서 마이크로 커널의 모듈화 구조까지의 발전 과정


9. 가상 머신(Virtual Machine)과 Java 가상 머신(JVM)

가상 머신 구조 - 하나의 물리 하드웨어 위에 여러 VM이 동작하는 모습 가상화 소프트웨어가 각 VM에 독립적인 하드웨어 환경의 일루전을 제공한다

가상 머신은 물리적으로 하나의 컴퓨터를 논리적으로 여러 개의 독립적인 컴퓨터처럼 분할하여 사용하는 기술이다. 초기에는 고가의 컴퓨터 자원을 연구·개발 목적으로도 활용하기 위해 도입되었으며, 각 가상 머신은 서로 독립적으로 동작하여 상호 영향을 주지 않는다.

물리적 컴퓨터의 CPU 이용률이 약 10%, 메모리 이용률이 약 20%에 불과한 비효율을 해결하기 위해 가상 머신이 도입되었다.

  • 자원 분할 방식:
자원분할 방식
CPUCPU 스케줄링으로 각 VM에 비율 할당 (예: 50%, 30%, 20%)
메모리물리 메모리를 분할하여 각 VM에 할당
디스크파티션을 나누어 각 VM에 할당 (예: C, D 드라이브)
I/O 디바이스스풀링(SPOOL) 방식 활용
  • 호스트/게스트 운영 체제: 원래의 운영 체제를 호스트 OS, 각 가상 머신 위에서 동작하는 운영 체제를 게스트 OS라 한다. 예시로 FreeBSD, Windows NT, Windows XP가 각각 독립된 VM 위에서 동작할 수 있다.
  • 가상화 소프트웨어(Virtualization Software): 하드웨어와 각 VM 사이에 위치하여 각 VM이 독립적인 하드웨어를 가진 것처럼 느끼게 하는 “일루전(Illusion)”을 제공한다.
  • Java 가상 머신(JVM):
    • Java 프로그램(.class 파일)은 Java API(라이브러리)와 함께 로딩되어 Java 인터프리터에 의해 한 줄씩 번역·실행된다.
    • JVM이 설치된 어떤 컴퓨터(Windows, Linux, macOS 등)에서도 동일한 Java 프로그램을 실행할 수 있다는 플랫폼 독립성이 핵심 장점이다.
    • 단, 실행 대상 컴퓨터에 반드시 JVM이 설치되어 있어야 한다.

10. 운영 체제의 설치(Generation)와 부팅 과정

운영 체제의 제너레이션(Generation)은 새로운 컴퓨터에 운영 체제를 처음 설치(이식)하는 과정을 의미한다. 운영 체제 개발에는 막대한 시간과 비용이 소요되므로, 다양한 하드웨어 환경에서 동작할 수 있도록 설치 과정이 체계적으로 설계되어 있다.

  • SYSGEN 프로그램: 설치 시 가장 먼저 실행되며, 키보드 포트, 메모리 용량(예: 16GB), 마우스, 프린터 등 하드웨어 구성 요소 정보를 수집한다.
  • 부팅(Booting) 과정:
    1. 전원이 켜지면 메인보드의 ROM 칩에 저장된 부트스트랩 프로그램(Bootstrap Program)이 가장 먼저 실행된다.
    2. 부트스트랩 프로그램이 커널의 위치를 파악하고, 커널을 메모리에 로딩하여 실행시킨다.

펌웨어(Firmware): ROM에 저장된 프로그램으로, 하드웨어(딱딱함)와 소프트웨어(부드러움)의 중간 개념이다. 수정은 가능하지만 쉽게 변경할 수 없는 특성을 가진다.

This post is licensed under CC BY 4.0 by the author.