운영체제(Operating System) - 2. 운영체제 구조

@inup· April 06, 2025 · 16 min read

본 포스팅은 Abraham Silberschatz 저 『Operating System Concepts』(9th Edition)의 내용을 개인 학습 목적으로 요약·정리한 글입니다.

2.1 운영체제 서비스

img1 daumcdn

  • 운영체제는 프로그램과 사용자에게 프로그램 및 서비스를 실행하기 위한 환경을 제공한다.

사용자에게 유용한 기능을 제공하는 서비스

1. 사용자 인터페이스(User interface) 

1-(1) CLI : 문자열로 명령하는 인터페이스를 제공함. 

1-(2) Batch Interace : 디렉티브가 파일 형태로 입력되고, 파일을 통해 인터페이스를 제공함. 

1-(3) GUI : 가장 보편적. 그래픽 요소들을 통해 인터페이스를 제공함.

2. 프로그램 수행(Program Execution)

  • System은 Program을 메모리에 load해서 실행할 수 있어야 한다.
  • 프로그램이 정상적이든, 비정상적이든 실행을 끝낼 수 있어야 한다.

3. 입출력 작업(I/O Operation) 

  • 수행 중인 프로그램은 입출력을 요구할 수 있다.
  • 사용자는 보통 입출력 장치를 직접 제어할 수 없으므로, 운영체제가 입출력 수행의 수단을 제공해야 한다.

4. 파일 시스템 조작(File System Manipulation)

  • 프로그램은 파일을 읽고 쓸 수 있어야 하며, 이름에 의해 파일 생성/삭제/검색 등을 할 수 있어야 한다.
  • 이에 많은 OS들은 다양한 specific feature와 Performance feature를 제공하기 위해 다양한 파일 시스템을 제공한다.

5. 통신(Communication) 

  • 한 프로세스가 다른 프로세스와 정보를 교환해야 할 필요가 있는 상황이 많다.
  • 이러한 통신은 두 가지 방법(Shared Memory, Message Passing)에 의해 구현될 수 있다.

6. 오류 탐지(Error Detection)

  • 운영체제는 모든 가능한 Error를 항상 의식하고 있어야 한다.
  • Error는 CPU, Memory Hardware, I/O, 또는 User program에 의해 일어날 수 있다.

시스템 효율성을 보장하는 운영체제 서비스

7. 자원 할당(Resource Allocation)

  • 다수의 User가 존재하거나 다수의 작업들이 동시에 수행될 때, Resource를 적절히 할당해주어야 한다.
  • 예를 들어, CPU를 최대한 효율적으로 이용하기 위해 운영체제는 CPU Scheduling Routine이 CPU의 속도, 사용 가능한 레지스터 수 등의 다양한 요인을 고려하여 자원을 할당한다.

8. 회계(Accounting)

  • 사용자가 컴퓨터 자원을 어떻게, 얼마나 많이 사용하는지를 알 수 있도록 해야 한다.

9. 보호(Protection)와 보안(Security)

  • 보호(Protection) : 시스템 자원에 대한 모든 접근이 통제되도록 보장하는 것
  • 보안(Security) : 각 사용자가 자원에 대한 접근을 원할 때, 시스템에게 자기 자신을 인증하는 것에서부터 시작

2.2 사용자 OS 인터페이스

  • 명령 해석기(Command-Interpreter)

    • Shell = 명령 해석기의 한 종류 (명령 해석기를 사용자와 운영체제 사이에서 작동하게 해주는 껍데기(Interfaces))
    • 사용자가 입력한 명령어를 운영체제가 이해할 수 있게 해석하고 실행해주는 프로그램
  • GUI(Graphical User Interface)

    • CLI에 비해 사용자 친화적. 마우스/터치스크린 등을 이용.

2.3 시스템 콜 (System Calls)

image

  • 응용 프로그램(Application)이 운영체제와 통신하기 위한 방법
  • 시스템 콜은 User Space → Kernel Space를 연결하는 유일한 인터페이스
  • 그러나 대부분의 프로그래머들은 API를 통해 System Call을 호출한다.

    • 일반적으로 고급 언어(C,C++)로 프로그램을 작성
    • API를 사용 시 이식성이 높아짐
    • System Call을 직접적으로 사용하기 어려움
  • System Call을 직접 사용하는 경우

    img1 daumcdn1

    image1

  • API를 사용하는 경우

    image2

Linux 시스템 콜 예시

image3

  1. User Space의 사용자 애플리케이션이 getpid() 호출
  2. getpid 함수는 시스템콜 번호를 EAX 레지스터에 설정함 mov $NR_getpid, %eax
  3. 커널 진입 (int $0x80 어셈블리 명령을 실행하여 커널 모드로 진입)
  4. 커널의 공통 시스템 콜 진입 지점system_call 함수가 실행됨

    • 여기서 eax 레지스터의 값을 기준으로 시스템 콜 테이블에 접근
    • call system_call_table[eax]
  5. 시스템콜 번호(eax)에 따라 sys_getpid, sys_fork, sys_exit 등 커널 내부 구현 함수 호출
  6. 실제 커널 함수 실행 (sys_getpid)
  7. 결과 반환 → 사용자 공간 복귀

    • 결과를 eax 레지스터에 담고, syscall_exit 루틴을 통해 사용자 공간으로 복귀

시스템 콜 구현

  • 리눅스에서의 시스템 콜 구현 (시스템 콜을 추가할 때 올바른 순서)

    1. System Call 함수 정의

      • (예를들어) sys_hello() 이름의 커널에서 실행될 함수 작성 (kernel/ 내 디렉터리)

        image4

    2. System Call 번호 할당

      • 시스템 콜 번호는 아키텍처별 unistd.h 헤더 파일에 정의되어 있음 (리눅스 기준)
      • include/asm/unistd.h__NR_hello 번호 추가 image5
    3. System Call 함수 등록

      • arch/i386/kernel/vsyscall_sysenter.S에서 sys_hello 등록

        image6

        image7

        syscall_table 예시

    4. 커널 Rebuild & Test

      • make bzImage, make modules, qemu 등으로 빌드 & 테스트 수행
  • 사용자 정의 System Call 호출해보기 image8
  • 일반적으로 각 시스템 콜(System Call)에 숫자가 할당

    • 시스템 콜 인터페이스는 이 숫자에 따라 인덱싱된 테이블을 유지
    • 시스템 콜 인터페이스는 운영 체제 커널에서 의도된 시스템 콜을 호출하고, 시스템 콜의 상태 및 반환 값을 반환
  • 호출자는 시스템 호출이 어떻게 구현되었는지 구현 방법을 알 필요가 없음

    • 단지 API를 준수하고, 시스템 콜이 실행되면 OS가 무엇을 해주는지 이해하면 됨
    • OS 인터페이스의 대부분의 세부 사항은 API에 의해 프로그래머에게 숨겨짐
    • 런타임 지원 라이브러리(컴파일러와 함께 제공되는 라이브러리에 내장된 함수 집합)에 의해 관리

운영체제에 매개변수를 전달하기

  • 운영체제에 매개변수를 전달하는 방법은 크게 3가지가 있다.

    1. 레지스터에게 매개변수 전달

      • 그러나 경우에 따라 레지스터보다 더 많은 매개변수가 필요할 수 있음
    2. 메모리의 블록(또는 테이블)에 매개변수 저장하고, 해당 블록의 주소를 레지스터에 매개변수로 전달
    3. 매개변수를 블록이나 스택에 푸시하여 저장

      • 블록 및 스택 방식은 전달할 매개변수의 수나 길이에 제한을 두지 않음

image9

API - 시스템콜 - 운영체제 간의 관계

image10

  1. 사용자 프로그램(애플리케이션)이 API 함수 open() 을 사용

    • open() 은 C 표준 라이브러리에 정의된 API 함수
  2. API가 System Call Interface를 호출

    • syscall(SYS_open, ...) 같은 식으로 시스템 콜 번호와 인자를 준비함.
    • 이 과정은 사용자 모드에서 실행되고, SysCall 명령어 또는 시스템 콜 트랩을 통해 커널 모드로 전환함
  3. System Call Interface가 시스템 콜 테이블에서 번호에 맞는 적절한 함수를 찾아 실행
  4. 커널이 실제 자원 처리 ( = 파일 열기)

2.4 시스템 호출의 유형(Types)

  1. Process Control (프로세스 제어)

    • 정상적으로(end()), 혹은 비정상적으로(abort()) 종료
    • 적재(load), 수행(execute), 대기(wait) 등
  2. File Manipulation (파일 조작)

    • 열기(open), 닫기(close), 읽기(read), 쓰기(write), 위치변경(reposition)
  3. Device Manipulation (장치 조작)

    • 장치 요구(request), 방출(release), 읽기, 쓰기, 위치변경
  4. Information Maintance (정보 유지 보수)

    • 시간(time), 날짜(date) 반환
  5. Communication (통신)과 Protection (보호)

    • Message Passing Model

      • 통신하는 두 process가 정보를 교환하기 위해 서로 메시지를 주고받는다.
    • Shared Memory Model

      • 다른 process가 소유한 메모리 영역에 대한 접근을 하기 위해 System call을 사용한다.
    • 대부분의 System은 두 가지 모두를 구현한다.

2.5 시스템 프로그램

  • 시스템 프로그램은 시스템 유틸리티(System Utility)로 알려져 있으며, 프로그램 개발과 실행을 위해 보다 편리한 환경을 제공한다.
  • 시스템 프로그램은 파일 관리, 상태 정보, 파일 변경, 프로그래밍 언어 지원, 프로그램 적재와 수행, 통신, 백그라운드 서비스의 범주로 분류할 수 있다.

2.6 운영체제 설계 및 구현

  • 일반적인 목적의 OS는 매우 큰 프로그램이다
  • 운영체제의 다양한 구조화 방법들

    • Simple Structure : MS-DOS
    • More Complex: UNIX
    • Layered: 추상화
    • MicroKernel : Mach

1️⃣ MS-DOS

  • 간단한 구조. 가장 작은 공간에 최대의 기능을 제공
  • 모듈로 나누어지지 않음

    • User Program이 고장 나게 되면 시스템 전체가 고장나게 된다.
  • MS-DOS는 일부 구조를 가지고 있지만, 그 인터페이스와 기능의 수준은 잘 구분되어 있지 않음

    • 예를 들어, Application Program은 basic I/O routine을 통해 display와 disk drive에 직접 쓰기가 가능하다.

    img1 daumcdn2

2️⃣ UNIX

  • 유닉스는 커널과 시스템 프로그램의 두 가지 분리된 부분으로 구성됨

    image11

  • 시스템콜 Interface와 커널 Interface 사이의 모든 것이 커널이다.

    • 즉, 시스템콜 인터페이스 ~ (물리적) 하드웨어 사이의 모든 것 = 커널
  • 단일 레벨(커널)에서 시스템콜을 통해 파일 시스템, CPU 스케줄링, 메모리 관리 등의 다양한 기능을 제공

    • 이 Monolithic(돌덩이같은) 구조는 구현하기 어렵고, 유지 보수하기 어렵다는 단점이 있다.

3️⃣ 계층적 접근 (Layered)

  • OS는 여러 개의 레이어로 나누어지며, 각 레이어는 하위 레이어 위에 구축됨

    img1 daumcdn3

    • 최하위 층(Layer 0)는 Hardware이고, 최상위 층(Layer N)은 User Interface(UI)이다.
    • 적절한 hardware support가 있을 경우, 운영체제는 보다 적절하게 분할될 수 있다.
  • 계층적 접근의 장점

    • 구현과 디버깅이 간단하다
    • 하위 층부터 구현하며 상위 층을 시도하므로, 버그 발생 시 해당 층에서의 오류임을 바로 파악 가능하다
  • 계층적 접근의 단점

    • 여러 개의 계층을 적절히 정의하기가 어렵다.
    • 다른 유형보다 효율성(속도)가 느리다.
    • 시스템 호출이 모든 하위 레이어를 거쳐야 하므로, 각 레이어가 추가하는 오버헤드가 발생

4️⃣ 마이크로 커널 (Microkernels)

  • 커널에서 중요하지 않은 많은 부분을 제거하고, System 또는 User Space로 이동시킴

    • 즉, 마이크로한 커널 = 마이크로커널 구조
    • 마이크로커널의 주 기능 = User Program간의 Message 전달 (=Communication)

    image12

  • 마이크로커널 구조의 장점

    • 운영체제 확장이 용이하다 (모든 새로운 서비스는 User Space에 들어감)
    • 커널을 변경해야 한다고 하더라도, 크기 자체가 작아 변경할 부분이 많지 않다
  • 마이크로커널 구조의 단점

    • System-Function의 overhead가 증가하여 성능이 나빠진다

5️⃣ 모듈 (Modules) 구조

  • 많은 현대 운영 체제는 로드 가능한 커널 모듈을 구현 (현대 Linux 등)

    • 객체지향 접근방식을 사용
    • 각 핵심 구성요소는 분리되어 있음
    • 각 구성요소는 정의된 인터페이스를 통해 서로 통신
    • 필요한 경우 커널 내에서 로드 가능
  • 각 부분이 별도 정의되고 Protected Interface를 가진다는 점에서 계층적 구조와 비슷하다.

    • 하지만, 모듈에서 임의의 다른 모듈을 호출할 수 있다는 점에서 계층적 구조보다 유연하다.

6️⃣ 하이브리드 시스템 (Hybrid Systems)

  • 하나의 구조만을 채택한 운영체제는 거의 존재하지 않으며, 보통 여러 구조를 결합한 혼용 구조로 구성된다.

    • Linux는 Monolithic 구조임과 동시에 새로운 기능을 동적으로 추가 가능한 Module을 사용
    • Windows도 Monolithic + 동적 적재 가능한 커널 모듈 지원
@inup
언제나 감사합니다 👨‍💻