2 운영체제 개요

프로그램이 실행될 때 어떤 일이 일어나는가?

  • 프로그램은 매우 단순한 일을 한다.
    • 명령을 실행한다.
    • 프로세서는 명령어를 초당 수백만~수십억번 반입(fetch)하고, 해석(decode)하고, 실행(execute)한다.
    • 명령어 작업을 완료한 후 프로세서는 프로그램이 완전히 종료될 때까지 다음 명령어로.. 다음 명령어로 실행을 계속한다.
    • 이것이 Von Neumann 컴퓨팅 모델의 기초에 해당한다.

운영체제(Operating System, OS)

  • 프로그램을 쉽게 실행하고, 동시에 여러 프로그램을 실행하기도 하고,
  • 프로그램 간의 메모리 공유를 가능하게 하고,
  • 장치와 상호작용을 가능하게 하고,
  • 다양하고 흥미로운 일을 할 수 있게 해주는 소프트웨어.
  • 시스템을 사용하기 편리하면서 정확하고 올바르게 동작시킬 책임이 있다.

운영체제는 앞에서 언급한 일을 하기 위해 가상화(virtualization)라고 불리는 기법을 사용한다.

  • 프로세서, 메모리, 디스크 같은 물리적 자원으로 사용이 편리한 가상(virtual) 형태의 자원을 생성한다.
    • 운영체제는 사용자에게 API, 표준 라이브러리를 제공한다.
  • 왜 가상화를 하는가?
    • 시스템을 사용하기 편리하게 만들기 위해서이다.
  • 가상화를 통해…
    • 많은 프로그램들이 CPU를 공유해서 동시에 실행 가능해진다.
    • 프로그램들이 각자 명령어와 데이터에 접근할 수 있게 된다.
    • 프로그램들이 디스크 등의 장치를 공유할 수 있다.

CPU, 메모리, 디스크는 시스템의 자원이다. 효율적으로 공정하게, 이들 자원을 관리하는 것이 운영체제의 역할이다.

2.1 CPU 가상화

예제 프로그램: 프로세서가 하나밖에 없는데도 프로그램 4개가 동시에 실행되는 것처럼 보이는 예제.

  • CPU 가상화(virtualizing the CPU): 운영체제가 시스템에 많은 수의 가상 CPU가 존재하는 것처럼 하여, 동시에 많은 수의 프로그램을 실행시킨다.

2.2 메모리 가상화

컴퓨터의 물리 메모리 모델은 매우 단순하다.

  • 물리 메모리 모델: 단순한 바이트의 배열.
    • 메모리를 읽고 쓰거나 갱신하려면 주소(address)를 명시해야 한다.

예제 프로그램

  • 예제: 각각 같은 주소(0x200000)를 할당받는데, 여러번 실행시켜 보면 각각 독립적으로 0x200000 주소의 값을 갱신한다.
    • 예제를 통해 알 수 있는 것:
      • 각 프로그램은 물리 메모리를 다른 프로그램과 공유하고 있지 않다.
      • 마치 각자 자신의 메모리를 갖고 있는 것처럼 보인다.
  • 운영체제가 메모리 가상화(virtualizing memory)를 하기 때문에 이런 현상이 생긴 것.
    • 각 프로세스는 자신만의 가상 주소 공간(virtual address space)을 갖는다.
      • 그냥 주소 공간(address space) 이라고도 부른다.
    • 운영체제는 가상 주소 공간을 컴퓨터의 물리 메모리로 매핑(mapping)한다.
      • 한 프로그램이 수행하는 메모리 연산은 다른 프로그램의 주소 공간에 영향을 주지 않는다.
      • 프로그램마다 자신만의 물리 메모리를 갖는 셈.
      • 물리 메모리는 공유 자원이고, OS가 관리한다.

2.3 병행성(concurrency)

병행성 문제는 운영체제 자체에서 발생한다.

  • 운영체제는 여러 프로세스를 실행시켜 한 번에 많은 일을 한다.

병행성 문제는 운영체제만의 문제가 아니다. 멀티 스레드 프로그램에서도 같은 문제가 발생한다.

예제 프로그램

  • 예제: 스레드 2개를 생성해 카운터를 증가시키는 프로그램.
    • loop 값을 1000 으로 줬더니 2개 스레드가 카운터를 증가시켜서 카운터의 최종값이 2000 이 나옴. 정상.
    • loop 값을 10만 으로 줬더니 2개 스레드가 카운터를 증가시켰고, 카운터의 최종값이 20만이 아니라 14만 3012가 나옴.
      • 카운터 값을 증가시키는 명령은 3개로 이루어져 있음.
        • 명령1. 카운터 값을 메모리에서 레지스터로 탑재하는 명령
        • 명령2. 레지스터를 1 증가시키는 명령
        • 명령3. 레지스터의 값을 다시 메모리에 저장하는 명령
      • 3개의 명령이 원자적으로 실행되지 않기 때문에 이런 이상한 결과가 나올 수 있음.

2.4 영속성(persistence)

DRAM과 같은 장치는 데이터를 휘발성(volatile) 방식으로 저장한다.

  • 따라서 메모리의 데이터는 쉽게 손실될 수 있다.
  • 데이터를 영속적으로 저장할 수 있는 하드웨어와 소프트웨어가 필요하게 된다.
  • 저장 장치는 모든 시스템에 필수적이다.

디스크를 관리하는 OS 소프트웨어를 파일 시스템(file system)이라 부른다.

  • 파일 시스템은 file을 시스템의 디스크에 안전하고 효율적인 방식으로 저장할 책임이 있다.
  • CPU 가상화, 메모리 가상화와는 달리 OS는 프로그램별로 '가상 디스크'를 따로 생성하지 않는다.

데이터를 디스크에 쓰기 위해서 OS가 실제로 하는 일

  • 새 데이터가 디스크의 어디에 저장될지 결정해야 한다.
  • 파일 시스템이 관리하는 다양한 자료 구조를 통해 데이터의 상태를 추적해야 한다.
    • 저장 장치로부터, 기존 자료 구조를 읽거나 갱신해야 한다.
    • 장치 드라이버(device driver)
  • OS는 시스템 콜이라는 표준화된 방법으로 각종 장치에 접근할 수 있게 해준다.

대부분의 파일 시스템은 응용 프로그램들이 요청한 쓰기 요청들을 모아서 한번에 처리한다.

  • 성능향상을 위해서이다.
  • 응용 프로그램 입장에서 보면 쓰기 요청을 해도 실제로 기록될 때까지 딜레이가 좀 있게 된다.
    • 디스크에 실제로 기록되기 전에 '정전' 같은 문제가 발생하면 기록 요청한 데이터가 손실될 수 있다.
    • 기록 순서가 바뀔 수도 있다.
  • 쓰기 중에 시스템이 갑자기 고장날 때를 대비해 많은 파일 시스템들은 다음과 같은 기법들을 사용한다.
    • 저널링(journaling)
    • 쓰기 시 복사(Copy-On-Write)
  • 이런 기법들은…
    • 고장이 발생해도 시스템을 정상 상태로 복구될 수 있게 한다.
    • 쓰기 명령들 간 기록 순서를 강제로 보장한다.
  • 효율적인 디스크 작업을 위해 다양한 자료 구조를 사용한다.
    • 단순한 링크드 리스트부터 복잡한 B-트리까지.

2.5 설계 목표

운영체제가 실제로 하는 일들

  • CPU, 메모리, 디스크 같은 물리 자원을 가상화한다.
  • 병행성(concurrency)과 관련된 복잡한 문제를 처리한다.
  • 파일을 영속적으로 저장해 오랜 시간 동안 안전한 상태에 있게 한다.

이런 시스템을 구현하려면 몇 가지 목표를 세워야 하고, 필요하다면 트레이드 오프를 선택해야 한다.

  • 가장 기본적인 목표: 시스템을 편리하고 사용하기 쉽게 만드는 데 필요한 개념(abstraction)들을 정의하는 것.
    • 컴퓨터 과학에서 추상화는 모든 일의 근간이 된다.
    • 추상화를 통해 큰 프로그램을 이해하기 쉬운 작은 부분들로 나누어 구현할 수 있다.
  • 중요한 목표: 성능.
    • 오버헤드를 최소화(minimize the overhead)하는 것.
    • "가상화"와 "사용하기 쉬운 시스템 만들기"는 의미는 있지만 반드시 해야 하는 일은 아니다.
    • 가상화 등의 OS 기능들을 과도한 오버헤드 없이 제공해야 한다.
  • 또 다른 목표: 응용 프로그램들 간의 보호, 운영체제와 응용 프로그램 간의 보호.
    • 여러 프로그램들이 동시에 실행되기 때문.
    • OS는 한 프로그램의 악의적인/의도치 않은 행위가 다른 프로그램에 피해를 주지 않는다는 것을 보장해야 한다.
    • 응용 프로그램에 OS에 해를 끼치지 않도록 한다.
    • 보호는 OS의 원칙 중 하나인 고립(isolation) 원칙의 핵심이다.
    • 프로세스를 다른 프로세스로부터 고립시키는 일은 보호의 핵심이고, OS가 해야 하는 일 중 많은 부분의 근간이 된다.
  • 목표: 높은 수준의 신뢰성(reliability)
    • OS는 계속 실행되어야 한다.
    • OS가 실패하면 OS 위에서 실행되는 애플리케이션들도 실패한다.
    • OS가 복잡해질수록 신뢰성 있는 OS를 구현하는 일도 매우 어려워진다.
  • 목표: 에너지 효율성(energy-efficiency)
  • 목표: 보안(security).
    • 보호의 확장.
  • 목표: 이동성(mobility).
    • 작은 장치에서 OS들이 사용될수록 중요해짐.

시스템의 목적에 따라 OS는 각자 다른 목표를 지향하게 되고, 구현도 달라질 수 있다.

2.6 배경 소개

OS 역사에 있어서의 몇 가지 주요 발명들.

  • 초창기 OS: 단순 라이브러리
    • 초창기 운영체제는 자주 사용되는 함수들을 모아둔 라이브러리에 불과했다.
    • 옛날 메인프레임 시스템에서는 현재 OS가 담당하는 많은 일들을 컴퓨터 관리자가 담당했다.
      • 작업의 순서를 정해주는 것 등.
      • 프로그래머들은 컴퓨터 관리자에게 잘 보여야 했다.
      • 컴퓨터 관리자는 여러 작업을 일괄적으로 처리했다. 이런 방식의 컴퓨팅을 batch 라고 불렀다.
      • 당시의 컴퓨터는 너무 비싸서, 사람이 앞에 앉아서 사용하게 하지 않았다.
  • 라이브러리를 넘어서: 보호
    • 컴퓨터 관리 면에서 중요한 역할을 하게 됨.
    • OS 코드는 하드웨어 장치를 제어하므로, 일반적인 애플리케이션 코드와는 다르게 취급되어야 한다.
    • Atlas 컴퓨팅 시스템에서 '시스템 콜'이라는 아이디어가 발명됐다.
      • 시스템 콜과 프로시저 호출의 차이점:
        • 제어를 OS에 넘길 때, 시스템 콜은 하드웨어 특권 수준을 상향 조정 받는다.
        • 사용자 응용 프로그램은 사용자 모드(user mode) 상태에서 실행된다.
          • 사용자 모드는 할 수 있는 일이 하드웨어적으로 제한받는다.
          • 사용자 모드에서는 디스크 입출력, 물리 메모리 페이지 접근, 네트워크 패킷 송신 등의 작업을 할 수 없다.
        • 시스템 콜은 trap 이라 불리는 특별한 하드웨어 명령어를 이용해 호출된다.
          • 시스템 콜이 시작되면 하드웨어는 미리 지정된 트랩 핸들러 함수에게 제어권을 넘기고 특권 수준을 kernel mode로 격상시킨다.
          • trap 핸들러 함수는 OS가 미리 구현해 놓는다.
          • kernel mode에서 OS는 시스템의 하드웨어를 자유롭게 접근할 수 있으며, 입출력, 메모리 할당 등의 작업을 할 수 있다.
          • OS가 서비스를 완료하면 return-from-trap 특수 명령어를 사용해 제어권을 다시 사용자에게 넘기고, 사용자 모드로 다시 전환한다.
  • 멀티 프로그래밍 시대
    • 메인 프레임 이후 미니컴퓨터 시대가 옴.
    • 컴퓨터 자원의 효율적 활용을 위해 멀티프로그래밍 기법이 대중화됨.
    • 한번에 하나의 프로그램만 실행시키는 대신, OS는 여러 작업을 메모리에 탑재하고 작업들을 빠르게 번갈아 가며 실행해, CPU 사용률을 향상.
    • 멀티프로그래밍 지원의 필요, 인터럽트를 통한 입출력 작업 처리 등
      • 운영체제의 발전에 여러 혁신을 가져다 주었다.
      • 이로 인해 메모리 보호(memory protection)와 같은 주제가 중요해졌다.
      • 멀티프로그래밍에서 발생하는 병행성(concurrency) 문제에 대한 이해가 중요해졌다.
    • UNIX OS의 등장.
      • Bell 연구소의 Ken Tompson과 Dennis Ritchie가 만들었다.
      • UNIX는 다른 OS로부터 좋은 아이디어를 많이 도입했음.
        • Multics, TENEX, Berkeley Time-Sharing System 등으로부터.
        • UNIX는 이런 아이디어들을 더 단순하고 사용하기 쉽게 변형했다.
  • 현대
    • PC 등장.
    • OS 입장에서는 PC의 등장으로 인해 퇴보하게 되었다.
      • 초기 PC들은 미니컴퓨터 기술로부터 얻었던 소중한 경험들을 무시하거나, 잘 모르고 있었다.
      • DOS 같은 초기 OS는 메모리 보호가 중요하다는 생각을 하지 않았다.
        • 악의적인/잘못 개발된 애플리케이션이 메모리 전체를 손상시킬 수 있었음.
      • 1세대 Mac OS는 작업 스케쥴링에 협업 스케쥴링(Cooperative Scheduling)을 채용했다.
        • 쓰레드가 무한 루프에 빠지면 전체 시스템을 정지시켜서 재부팅 밖에 답이 없었음.
      • 이 세대에 사라져버린 OS 기술들이 너무 많음.
    • 암흑기가 지난 뒤, 예전 미니컴퓨터 OS 기법들이 데스크톱 컴퓨터용 OS에 등장하기 시작.
      • Mac OS X: UNIX를 근간으로 하고, UNIX의 모든 특성을 갖고 있음.
      • Windows: 컴퓨팅 역사의 위대한 아이디어 중 많은 것들을 채택.
        • Windows NT 부터 이런 노력이 시작됐음. NT는 Microsoft OS 기술을 크게 발전시켰음.
      • 휴대전화: Linux 같은 OS를 실행하고 있음.
        • Linux는 1980년대 PC용 OS보다, 1970년대 미니컴퓨터용 OS에 가까운 훌륭한 물건.
      • OS 전성기에 개발된 좋은 아이디어들이 현재 시스템에서도 여전히 적용되고 있고, 계속 발전중.