개발자는 기록이 답이다

혼공 컴퓨터구조 + 운영체제 9. 운영체제 시작하기 본문

CS/운영체제

혼공 컴퓨터구조 + 운영체제 9. 운영체제 시작하기

slow-walker 2024. 1. 28. 19:01

 

1. 운영체제를 알아야 하는 이유

 

운영체제란

 

모든 프로그램은 하드웨어를 필요로 한다.

  •  1 + 2를 계산하는 프로그램은 CPU를 필요로 하고, 이미지를 하드 디스크에 저장하는 프로그램은 하드 디스크를 필요로 한다.
  • 프로그램 실행에 마땅히 필요한 요소들 : 시스템 자원(자원)

 

지금까지 학습한 CPU, 메모리, 보조기억장치, 입출력 장치 등과 같은 컴퓨터 부품들은 모두 자원이라고 할 수 있다.

즉, 모든 프로그램은 실행되기 위해 반드시 자원이 필요하다.

 

운영체제(Operating system) : 실행할 프로그램에 필요한 자원을 할당하고, 프로그램이 올바르게 실행되도록 돕는 특별한 프로그램 

 

운영체제는 인터넷, 브라우저, 게임과 같은 프로그램이다. 그래서 운영체제 또한 어느 프로그램과 마찬가지로 메모리에 적재되어야 한다. 

다만 운영체제는 매우 특별한 프로그램이기 때문에 항상 컴퓨터가 부팅될 때 메모리 내 커널 영역이라는 공간에 따로 적재되어 실행된다. 

커널 영역을 제외한 나머지 영역, 사용자가 이용하는 응용 프로그램이 적재되는 영역을 사용자 영역이라고 한다. 즉, 운영체제는 커널 영역에 적재되어 사용자 영역에 적재된 프로그램들의 자원을 할당하고 이들이 올바르게 실행되도록 돕는다.

 

 

예를 들어, 일반적으로 메모리에는 여러개의 응용프로그램이 사용자 영역에 저장되어 실행된다. 

  • 응용 프로그램 : 사용자가 특정한 목적을 위해 사용하는 일반적인 프로그램을 의미
  • 일상적으로 사용하는 워드프로세서, 인터넷 브라우저, 메모장, 게임 등과 같은 프로그램이 모두 응용프로그램이다. 

운영체제가 필요한 상황

  •  프로그램들을 메모리 주소가 겹치지 않도록 적당한 공간에 프로그램을 적재하기 위해
  • 실행할 프로그램을 메모리에 적재하고, 더 이상 실행되지 않는 프로그램을 메모리에서 삭제하며, 계속 메모리 자원 관리
  • 응용 프로그램이 실행되려면 반드시 CPU가 필요한데, 이 문제 또한 운영체제가 해결한다. 
    • 어떤 프로그램부터 CPU를 사용해야 할지?
    • 얼마나 오랫동안 CPU를 이용하게 해야 할지?
  • 어느 한 프로그램이 CPU를 독점하면 다른 프로그램들은 올바르게 실행될 수 없기 때문에 운영체제는 최대한 공정하게 여러 프로그램의 CPU 자원을 할당한다.

 

▶ 예시 : 워드 프로세스와 메모장이 동시에 동일한 프린터를 이용하려고 하는 상황

  • 운영체제는 동시에 두 개의 프로그램이 프린터를 사용하지 못하도록 막고, 하나의 프로그램이 프린터를 이용하는 동안 다른 프로그램은 기다리게 만들어 프린터 자원을 관리한다.

 

 

운영체제는 관리할 자원별로 기능이 나누어져 있다. 예를 들어, 운영체제의 어느 한 부분에서는 CPU, 어느 한 부분에서는 메모리, 어느 한 부분에서는 하드디스크를 관리한다.

 

운영체제를 알아야 하는 이유

 

아무리 간단한 프로그램이라도 운영체제가 없다면 하드웨어를 조작하는 코드를 개발자가 모두 직접 작성해야 한다.

 

 1 더하기 2를 더한 결과를 모니터에 출력하는 간단한 프로그램

 

이런 간단한 프로그램조차도 운영체제가 없다면 작성하기조차 매우 어렵다.

  • 프로그램을 메모리에 적재하는 코드
  • CPU로 하여금 1과 2를 더하게 하는 코드
  • 모니터에 계산 결과를 출력하는 코드

 

하지만 다행히도 운영체제가 하드웨어를 조작하고 관리하는 기능들을 제공하기 때문에 개발자는 하드웨어를 조작하는 코드를 직접 작성할 필요 없이 운영체제의 도움을 받아 간편하게 개발할 수 있다.

 

그렇다면 개발자들이 왜 운영체제를 알아야 할까? 문제 해결 능력과 관련이 있다.

 

우리가 만든 프로그램은 결국 하드웨어가 실행하고 그 하드웨어를 조작하는 프로그램이 운영체제이다.

 

운영체제는 우리의 프로그램이 하드웨어상에서 어떻게 동작하는지를 우리보다 먼저 더 자세히 알고 있다.

그리고 운영체제는 현재 하드웨어의 상태는 어떠한지 우리의 코드가 어떻게 실행되었는지 하드웨어상에서 어떤 문제가 있는지 우리에게 상세하게 알려줄 수 있고 이를 통해 우리는 문제를 해결할 수 있다.

 

 

▶ 대표적인 예시 : 오류 메시지

 

우리가 접하게 되는 대다수의 오류 메시지 근원은 운영체제이다. 우리가 작성한 소스코드를 하드웨어가 제대로 실행하지 못하면 운영체제는 우리에게 오류 메시지를 띄워준다. 프로그래밍 문법만 학습한 사람들은 운영체제의 메시지를 이해하기가 어렵고 문제를 진단하고 해결하기가 어렵다.

 

2. 운영체제의 큰 그림

 

운영체제의 심장, Kernel

 

운영체제는 현존하는 프로그램 중 규모가 가장 큰 프로그램 중 하나이다. 대표적인 운영체제인 Linux를 구성하는 소스코드는 천만 줄이 넘는다. 또 세상에는 다양한 운영체제가 있다. 그래서 운영체제가 인용 프로그램에 제공하는 기능들, 달리 말해 운영체제 서비스 또한 매우 다양하다. 

 

  • 스마트폰이 사용자에게 제공하는 서비스 종류는 다양하다
    • 그 중에서 핵심적인 서비스 :  전화, 문자, 인터넷 기능
  • 운영체제가 응용 프로그램에 제공하는 서비스 종류는 다양하다
    • 그 중에서 가핵심적인 서비스 : 자원에 접근하고 조작하는 기능, 프로그램이 올바르게 안전하게 실행되게 하는 기능

 

Kernel : 운영체제의 핵심 서비스를 담당하는 부분

 

 운영체제가 설치된 모든 기기에는 Kernel이 있다. Kernel은 마치 사람의 심장, 혹은 자동차의 엔진과도 같다.

 

어떤 Kernel을 사용하는지에 따라 실행하고 개발하는 프로그램들이 하드웨어를 이용하는 양상이 달라지고, 결과적으로 컴퓨터 전체의 성능도 달라질 수 있다.

 

운영체제가 제공하는 서비스 중 커널에 포함되지 않는 서비스도 있는데 대표적으로 사용자 인터페이스이다.

 

사용자 인터페이스(user Interface)는 윈도우의 바탕화면과 같이 사용자가 컴퓨터와 상호작용할 수 있는 통로이다.

 

운영체제가 제공하는 사용자 인터페이스 종류

  • 그래픽 유저 인터페이스(GUI:Graphic User Interface)
  • 커맨드 라인 인터페이스 (CLI : Comman User Interface)

 

전자는 윈도우 바탕화면이나 스마트폰의 화면처럼 그래픽을 기반으로 컴퓨터와 상호작용할 수 있는 인터페이스이고, 후자는 명령어를 기반으로 컴퓨터와 상호작용할 수 있는 인터페이스이다.

 

사용자는 컴퓨터를 사용하기 위해 정해진 명령어를 입력함으로써 컴퓨터와 상호작용할 수 있다. 이러한 사용자 인터페이스는 운영체제가 제공하는 서비스이지만, 이는 그저 컴퓨터와 상호작용하기 위한 통로일 뿐 커널에 속한 기능이 아니다. 실제로 같은 커널을 사용하더라도 사용자 인터페이스는 다를 수 있다.

 

이중 모드와 시스템 호출

 

운영체제는 사용자가 실행하는 응용 프로그램이 하드웨어 자원에 접근하는 것을 방지해 자원을 보호한다. 

만약 응용 프로그램이 CPU, 메모리, 하드디스크 등이 마음대로 접근하고 조작할 수 있다면 자원이 무질서하게 관리될 것이고, 응용 프로그램이 조금만 실수해도 컴퓨터 전체에 큰 영향을 끼칠 수 있다. 

 

그래서 운영체제는 응용 프로그램들이 자원에 접근하려고 할 때, 오직 자신을 통해서만 접근하도록 해서 자원을 보호한다.

 

응용 프로그램이 자원에 접근하기 위해서는 "운영체제에 도움을 요청한다"."운영체제 코드를 실행하려고 한다".

 

응용 프로그램의 요청을 받은 운영체제는 응용 프로그램 대신 자원에 접근해 요청한 작업을 수행한다.

 

 예시 : 응용 프로그램이 실행 과정에서 하드디스크에 접근해서 데이터를 저장하려면 운영체제에게 도움을 요청해야 하고, 운영체제는 커널 영역 내 하드디스크에 데이터를 저장하는 코드를 실행하여 응용 프로그램의 작업을 대신 수행해준다. 

 

 

이러한 운영체제의 본질의 역할은 이중 모드로서 구현된다.

  • 이중 모드(dual mode) :  CPU가 명령어를 실행하는 모드를 크게 사용자 모드와 커널 모드로 구분하는 방식
    • CPU는 명령어를 사용자 모드로서 실행할 수도 있고 커널 모드로서도 실행할 수 있다.

  • 사용자 모드(user mode) : 운영체제 서비스를 제공받을 수 없는 실행 모드
    • 즉, 커널 영역의 코드를 실행할 수 없는 모드
    • 일반적인 응용 프로그램은 기본적으로 사용자 모드로 실행된다.
    • 사용자 모드로 실행 중인 CPU는 입출력 명령어와 같이 하드웨어 자원에 접근하는 명령어를 실행할 수 없다.
    • 그래서 사용자 모드로 실행되는 일반적인 응용 프로그램은 자원에 접근할 수 없다.
  • 커널 모드(kernal mode) : 운영체제 서비스를 제공받을 수 있는 실행 모드이다.
    • 즉, 커널 영역의 코드를 실행할 수 있는 모드이다.
    • CPU가 커널 모드로 명령어를 실행하면 자원에 접근하는 명령어를 비롯한 모든 명령어를 실행할 수 있다.
    • 운영체제는 커널 모드로 실행되기 때문에 자원에 접근할 수 있다.

 CPU가 사용자 모드로 실행 중인지 커널 모드로 실행 중인지는 플래그 레지스터 속 슈퍼바이저 플래그를 보면 알 수 있다.

 

 

사용자 모드로 실행되는 프로그램이 자원에 조건하는 운영체제 서비스를 제공받으려면 운영체제의 요청을 보내 커널 모드로 전환되어야 한다.

 

  • 시스템 호출(system call) : 운영체제 서비스를 제공받기 위해 커널 모드로 전환하는 방법
    • 사용자 모드로 실행되는 프로그램은 시스템 호출을 통해 커널 모드로 전환하여 운영체제 서비스를 제공받을 수 있다.

시스템 호출은 일종의 인터럽트이다. 정확히는 소프트웨어적 인터럽트이다. 인터럽트는 입출력 장치에 의해 발생하기도 하지만, 인터럽트를 발생시키는 특정 명령어에 의해 발생하기도 하는데, 이를 소프트웨어 인터럽트라고 한다.


그래서 CPU가 시스템 호출을 처리하는 순서는 4장에서 설명한 인터럽트 처리 순서와 비슷하다. 시스템 호출을 발생시키는 명령어가 실행되면, CPU는 지금까지 작업을 백업하고, 커널 영역 내에 시스템 호출을 수행하는 코드(인터랩트 서비스 루틴)을 실행한 뒤, 다시 기존에 실행하던 응용 프로그램으로 복귀해서 실행을 계속해 나간다.

 

▶ 시스템 호출의 작동을 예

 

한 응용 프로그램이 하드디스크에 데이터를 저장하려 한다고 가정해보자.

 

이를 위해 응용 프로그램은 하드디스크에 접근을 해야한다.

하지만 사용자 모드로 실행되는 동안에는 자원, 즉 하드디스크에 접근을 할 수 없기 때문에 커널 모드로 전환을 해야 한다.

  • 이를 위해 응용 프로그램은 1번 하드디스크에 데이터를 저장하는 시스템 호출을 발생시켜 커널 모드로 전환하고
  • 2번 운영체제 내에 하드디스크에 데이터를 저장하는 코드를 실행함으로써 하드디스크에 접근을 할 수 있다.
  • 3번 그리고 하드디스크에 접근이 끝났다면 다시 사용자 모드로 복귀하여 실행을 계속해 나간다.

일반적으로 응용 프로그램은 실행 과정에서 운영체제 서비스들을 매우 빈번하게 이용한다. 그 과정에서 빈번하게 시스템 호출을 발생시키고 사용자 모드와 커널 모드를 오감하여 실행한다.출을 발생시키고 사용자 모드와 커널 모드를 오가며 실행한다.

운영체제의 핵심 서비스

 

 

1) 프로세스 관리

 

실행 중인 프로그램을 프로세스라고 한다. 

윈도우의 [작업관리자] → [프로세스 항목]을 살펴보면 굉장히 많은 프로세스가 실행 중인 것을 알 수 있다. 

 

이처럼 컴퓨터를 사용하는 동안 메모리 안에서 새로운 프로세서들이 마구 생성되고 사용되지 않는 프로세서는 메모리에서 삭제된다. 

일반적으로 CPU는 한 번에 하나의 프로세스만 실행할 수 있기에 CPU는 이 프로세서들을 조금씩 번갈아가며 실행한다.

CPU는 한 프로세서를 실행하다가 다른 프로세서로 실행을 전환하고 그 프로세서를 실행하다가 또 다른 프로세서로 실행을 전환하는 것을 반복한다.

 

이때 각 프로세스는 상태, 사용하고자 하는 자원 등은 다양하다.

입출력 장치를 주로 사용하는 프로세스도 있고 입출력 장치는 거의 사용하지 않고 주로 CPU만 사용하는 프로세스도 있다. 또 당장 실행할 수 있는 프로세스가 있는 반면에 당장 실행이 불가능한 프로세스도 있다.

그래서 운영체제가 다양한 프로세스를 일목요연하게 관리하고 실행할 수 있어야 한다.

  • 10장 : 운영체제가 다양한 프로세스를 어떻게 관리하고 실행하는지
  • 12~13장 : 여러 프로세스가 동시에 실행되는 환경에서는 프로세스 동기화가 필수적이고 프로세스가 꼼짝도 못하고 더 이상 실행되지 못하는 상황인 교착상태를 해결해야 한다.

 

2) 자원 접근 및 할당

 

운영체제가 CPU, 메모리, (보조기억장치와) 입출력 장치를 어떻게 관리하고 결과적으로 어떤 기능을 제공하는지 알아보자

 

▶ CPU

 

일반적으로 메모리에는 여러 프로세스가 적재되고, 하나의  CPU는 한 번에 하나의 프로세스만 실행할 수 있다.

그래서 하나의 프로세스가 CPU를 이용하고 있다면 다른 프로세스는 기다려야 한다.

  • CPU스케줄링 : 운영체제는 프로세스들에 공정하게 CPU를 할당하기 위해 어던 프로세스부터 CPU를 이용하게 할 것인지, 얼마나 오래 CPU를 이용하게 할지를 결정할 수 있어야 한다 (11장)

 메모리


메모리에 적재된 프로세스들은 크기도 적재되는 주소도 가지각색이다. 같은 프로세스라 할지라도 실행할 때마다 적재되는 주소가 달라질 수 있다. 그래서 운영체제는 새로운 프로세스가 적재될 때 마다 어느 주소에 적재해야 할지를 결정해야 한다.


때로는 메모리가 이미 꽉 차 있어 꼭 실행해야 할 프로세스를 적재할 공간이 없는 경우도 있고, 메모 리에 공간이 남았는 데도 불구하고 프로세스를 적재하지 못하는 상황도 발생한다.


운영체제가 프로세스에게 어떻게 메모리를 할당하는지, 그리고 메모리가 부족할 경우 이를 어떻게 극복하는지는 14장에서 다룬다.


▶ 입출력장치


인터럽트 서비스 루틴은 운영체제가 제공하는 기능으로 커널 영역에 있다. 입출력장치가 발생시키는 하드웨어 인터럽트도 마찬가지다. 입출력장치가 CPU에 하드웨어 인터럽트 요청 신호를 보내면 CPU는 하던 일을 잠시 백업한 뒤 커널 영역에 있는 인터럽트 서비스 루틴을 실행한다. 이 처럼 운영체제는 인터럽트를 처리하는 프로그램, 즉 인터럽트 서비스 루틴을 제공함으로써 입출력 작업을 수행한다.

 


3) 파일 시스템 관리


우리는 컴퓨터를 사용할 때는 여러 파일을 열고, 생성하고, 삭제하곤 합니다. 그리고 이 파일들을 한데 묶어 디렉터리(폴더)로 관리합니다. 자칫 당연해 보이는 이런 파일 시스템(file system)도 운영체제 가 지원하는 핵심 서비스이다. 운영체제가 보조기억장치 속 데이터를 어떻게 파일과 디렉터리로 관리하는지는 15장에서 배 우낟.


정리

  1. 운영체제의 핵심 서비스를 제공하는 부분을 커널이다.
  2. 사용자 프로세스가 커널의 서비스를 제공받기 위해서는(커널 영역의 코드를 실행하기 위해서는) 사용자 모드에서 커널 모드로 전환해야 하고, 이는 시스템 호출을 통해 이루어진다.
  3. 즉, 시스템 호출은 커널 모드로써 운영체제의 서비스를 제공 받을 수 있는 방법이다.
  4. 대표적인 커널의 서비스로는 프로세스 관리, 자원 접근 및 할당, 파일 시스템 관리가 있다.

 

가상 머신과 이중 모드의 발전

 

이중 모드는 커널 모드와 사용자 모드, 두 가지 모드를 지원하는 실행 모드이지만, 가상 머신을 통한 가상화를 지원하는 현대 CPU는 두 가지 모드 이상을 지원한다.

 

가상 머신 Virtual machine : 이름 그대로 소프트웨어적으로 만들어낸 가상 컴퓨터이다.

  • 가상머신을 설치하면 새로운 운영체제와 응용 프로그램을 설치하고 실행할 수 있다.
  • 가령 아래 사진과 같이 윈도우 운영체제에 가상 머신을 설치하면 가상 머신상에 리눅스 운영체제와 그를 기반으로 여러 응용 프로그램들을 설치하고 실행할 수 있다.

 

이때 우리 컴퓨터에 설치된 운영체제에서 가상 머신을 설치 및 실행한다면, 그 가상 머신 또한 응용 프로그램이다.  그래서 사용자 모드로 작동한다.

 

마찬가지로 가상 머신상에 설치된 운영체제(아래 예시 그림에서는 리눅스 운영체제) 또한 사용자 모드로 작동한다.

가상 머신에 설치된 응용 프로그램 (아래 예시 그림에서는 웹 브라우저)이 운영체제 서비스를 제공받기 위해서는 커널 모드 로 전환되어야 하는데, 가상 머신에 설치된 운영체제도 사용자 모드로 작동하면 운영체제 서비스를 제공받기 어렵다.

 

그래서 가상화를 지원하는 CPU는 커널 모드와 사용자 모드 이외에 가상 머신을 위한 모드인 하이퍼 바이저 모드를 따로 둔다. 이로써 가상 머신 상에서 작동하는 응용 프로그램들은 하이퍼바이저 모 드로써 가상 머신에 설치된 운영체제로부터 운영체제 서비스를 받을 수 있다.

 

시스템 호출은 운영체제 서비스를 제공받기 위한 방법이므로 시스템 호출 종류판 잘 파악해도 해당 운영체제를 깊이 이해할 수 있다.

유닉스, 리눅스 등의 운영체제(POSIX 운영체제)에서 사용하는 대표적인 시스템 호출의 종류에 대해 알아보자.

 

 

개발자가 작성하는 프로그래밍 언어들은 내부적으로 위와 같은 시스템 호출을 통해 실행된다. 

가령 C 언어에서 무언가를 화면에 출력하라는 코드인 printf도 내부적으로 시스템 호출을 통해 실행되고 사용자로부터 무언가를 입력받으리는 코드인 scanf도 내부적으로 시스템 호출을 통해 실행된다.

 

운영체제는 제공하는 서비스가 매우 다양하기에 시스템 호출의 종류도 다양하다.

system calls 항목에 리눅스 시스템 호출의 종류 정리 참고