OS Concepts 10th

[OS] Chapter 1-4. 운영체제의 작동

patrick-star 2023. 8. 1. 08:52
728x90

지금까지 컴퓨터 시스템 구성 및 아키텍처에 대한 내용을 전반적으로 살펴봤다. 이제 OS에 대해서 다뤄보도록 하겠다.

OS는 프로그램이 실행하는 환경을 제공한다. 이번 절에서는 여러 OS가 갖고 있는 공통적인 내용들에 대해서 살펴보도록 하겠다.

컴퓨터 전원을 켜거나 재부팅할 때와 같이 컴퓨터를 실행하려면 초기 프로그램을 실행해야 한다.
이러한 초기 프로그램 또는 부트스트랩 프로그램은 단순한 형태를 띠는 경향이 있다. 일반적으로 컴퓨터 HW 내에 펌웨어로 저장된다.
뿐만 아니라 CPU 레지스터, Device Controller, Memory content 까지 시스템의 모든 측면을 초기화한다.

부트스트랩 프로그램은 OS를 load하는 방법과 해당 시스템을 실행하는 방법을 알아야 한다.
때문에, 부트스트랩 프로그램은 OS Kernel을 찾아서 메모리에 적재해야 한다.

OS kernel을 적재해서 실행해야 시스템과 사용자에게 서비스를 제공할 수 있다.
여기에 일부 서비스는 커널이 실행되는 전체 시간동안 동작하는 system daemon이 되기 위해서 부팅할 때 메모리에 load되는 시스템 프로그램에 의해 커널 외부에서 제공된다. Linux의 첫 번째 시스템 프로그램은 systemd이며 다른 많은 daemon을 시작한다.
이 단계가 완료되면 시스템이 완전히 부팅되고 시스템은 어떤 이벤트가 발생할 때 까지 기다린다.

OS는 실행할 프로세스, 서비스할 I/O 장치 및 응답할 사용자가 없다면 이벤트가 발생할 때 까지 기다린다 .
이벤트는 거의 interrupt를 발생시키면서 신호를 보낸다.
이러한 인터럽트는 시스템 콜이라는 특수 연산을 실행해서 요청되고 OS가 제공하는 서비스가 수행될 것을 요구한다.

1. Multiprogramming & MultiTasking

OS의 가장 중요한 측면 중 하나는 여러 개의 프로그램을 실행할 수 있다는 것이다. 또한 사용자는 한 번에 2개 이상의 프로그램을 실행하기를 원한다.

  • Multi-programming

다중 프로그래밍(Multi-programming)은 CPU가 항상 1개의 프로그램은 실행할 수 있도록 함으로써 CPU의 활용률을 증가시키고 사용자의 만족도를 높인다. Multi-programming 시스템에서 실행 중인 프로그램을 프로세스(process)라고 한다.

OS는 여러 프로세스를 아래 그림과 같이 동시에 메모리에 유지한다. OS는 이러한 프로세스 중 하나를 선택해서 실행을 시작한다.

프로세스는 I/O 작업과 같은 일부 작업이 끝나기를 기다려야 할 수 있다.
이때, 다중 프로그래밍 시스템이 아니라면... CPU는 idle 상태(유휴 상태)가 될 수 있다.
다중 프로그래밍 시스템이라면... OS는 다른 프로세스로 전환해서 실행한다. 즉, 실행하고 있던 프로세스가 대기 상태라면 CPU는 실행하던 프로세스를 다른 프로세스로 전환한다.
대기하고 있던 프로세스의 대기가 끝나면 OS는 해당 프로세스를 실행한다(= CPU가 해당 프로세스로 전환해서 실행한다)

ex) 변호사 - 한 번에 여러 명의 의뢰인을 상대한다.

  • A 사건의 재판 결과를 기다리거나 문서 작성 등을 기다리는 동안
  • B 사건을 처리할 수 있다.

만약 변호사가 상대할 의뢰인이 충분히 많다면 변호사는 일이 없어서 쉬지 않게 된다.

  • Multi-tasking

다중 태스킹(Multi-tasking)은 다중 프로그래밍의 논리적 확장이다.
다중 태스킹 시스템에서 CPU는 여러 프로세스를 전환하며 프로세스를 실행하기 때문에 전환이 자주 발생하면서 사용자에게 빠른 응답 시간(response time)을 제공하게 된다.

ex) 프로세스가 실행할 될 때 I/O를 수행하기 전에 굉장히 짧은 시간 동안만 실행된다고 가정하자.

출력은 사용자를 위해 display되고 입력은 사용자의 키보드, 마우스 등으로 부터 들어온다.
이러한 대화식 입출력은 사람의 속도로 수행되다 보니 I/O 작업을 완료할 때 까지 CPU 입장에서는 상당히 긴 시간이 필요하다.

이러한 작업이 진행되는 동안 CPU를 idle 상태로 두지 않고 OS는 CPU를 다른 프로그램을 실행할 수 있도록 신속하게 전환한다.

동시에 여러 프로세스를 메모리에 유지하려면 9,10장에서 다룰 메모리 관리 방식이 필요하다. 또한 여러 프로세스들이 동시에 실행할 준비가 되면 시스템은 다음에 어떤 프로세스를 실행할 지 결정해야 한다. 이 결정을 내리는 건 5장에서 다룰 CPU 스케쥴링이다.
또한, 여러 프로세스를 병행해서 실행하려면 프로세스 스케쥴링, 디스크 저장장치 및 메모리 관리를 포함해 OS의 모든 단계에서 서로 영향을 미치는 기능이 제한되어야 한다. 이 책에 전반에 걸쳐 이러한 고려 사항에 대해서 논의한다.

다중 태스킹 시스템에서 OS는 적절한 응답 시간(response time)을 보장해야 한다. 이를 위해 사용하는 방법이 가상 메모리(virtual memory)이다. 이 기법을 통해 프로그래머는 메모리 저장장치의 한계로부터 자유로워진다. 자세한 내용은 10장에서 다루겠다.

뿐만 아니라 아래의 내용들도 전부 고려해야 한다.

  • 다중 프로그래밍 및 다중 태스킹 시스템에서 파일 시스템을 제공해야 함(13, 14, 15장)
  • 파일 시스템은 보조 저장장치에 존재하기 때문에 저장장치 관리가 제공되어야 한다.(11장)
  • 또한 부적절한 사용으로 부터 자원을 보호해야 한다.(17장)
  • 질서 있게 실행하려면 시스템은 프로세스 동기화 및 통신을 위한 기법을 제공해야 한다.(6, 7장)
  • 프로세스가 서로를 영원히 기다리는 교착 상태(deadlock)에 빠지지 않도록 보장해야 한다. (8장)

2. Dual Mode And Multimode operation

OS와 사용자는 컴퓨터 시스템의 HW및 SW 자원을 공유하기 때문에
올바르게 설계된 OS는 잘못된 프로그램으로 인해 다른 프로그램 또는 OS 자체가 잘못 실행되지 못하도록 보장해야 한다.

시스템을 올바르게 실행하려면... OS 코드 실행사용자-정의 코드 실행을 구분할 수 있어야 한다.
대부분의 컴퓨터 시스템이 사용하고 있는 접근 방식은 다양한 실행 모드차별화할 수 있는 HW 지원을 제공하는 것이다.

적어도 2개의 독립된 연산 모드.
사용자 모드(user mode), 커널 모드(kernel mode, privileged mode, system mode, supervisor mode)를 필요로 한다.
현재의 모드를 나타내기 위해서 컴퓨터의 HW에 모드 비트(mode bit)가 추가되었다.

  • 0 = 커널 모드
  • 1 = 사용자 모드

모드 비트를 사용해서 OS를 위해 실행되는 작업사용자를 위해 실행되는 작업을 구분할 수 있다.

컴퓨터 시스템이 user application을 실행할 때는 사용자 모드로 있게 된다.
하지만, user application이 OS의 service를 요청한다면 아래 그림과 같이 시스템 콜을 호출하고 나서 모드 비트를 사용자 모드에서 커널 모드로 전환해야 한다.

시스템 부팅 시

  • HW는 커널 모드에서 시작한다.
  • 이어 OS가 load되고
  • user mode에서 user process가 시작된다.
  • user process가 동작하다가 인터럽트가 발생한다면
  • HW는 사용자 모드를 커널 모드로 전환한다.

즉, OS가 컴퓨터의 제어권을 얻을 때 마다 항상 커널 모드로 있게 된다.
시스템은 user program으로 제어를 넘기기 전에 항상 사용자 모드(모드 비트를 1로 설정)로 전환한다.

동작의 이중 모드는 잘못된 사용자로 부터 OS와 사용자를 서로 보호하는 방법을 제공한다.
특히 악영향을 끼칠 수 있는 일부 명령들을 특권 명령(privileged instruction)(ex. 커널 모드로 전환하는 명령어, I/O 제어, 타이머 관리, 인터럽트 관리)으로 지정함으로써 보호한다.
HW특권 명령커널 모드에서만 수행되도록 허용한다.
만약에 사용자 모드에서 특권 명령을 실행하려고 하면 HW는 이를 실행하지 않고 kill해버린다.
(Intel 프로세서에서는 4개의 보호링 . ARMv8 시스템에서는 7가지 모드가 존재)

지금까지 살펴본 내용으로 컴퓨터 시스템에서 명령어 실행의 수명 주기를 더 잘 이해할 수 있다.

1) 초기 제어는 OS에 존재하고 커널 모드에서 실행된다.
2) user application으로 제어가 넘어가면 사용자 모드로 설정된다.
3) 인터럽트, 트랩 또는 시스템 콜을 통해 제어가 OS로 다시 전환된다.
MS Windows, Unix, Linux와 같은 대부분의 최신 OS에서 이러한 이중 모드 기능을 활용하고 있다.

시스템 콜(system call)은 user program을 대신해서 OS가 수행되도록 지정되어 있는 작업을 OS에게 요청할 수 있는 방법을 제공한다. 일반적으로 인터럽트 벡터의 특정 위치로 트랩을 거는 형태를 취한다.
이러한 트랩은 보통 trap 명령어를 통해 수행되지만 몇몇 시스템은 syscall 명령어를 가지기도 한다.

자세한 내용은 2.3절에서 다루도록 하겠다.

3. Timer

OS가 CPU에 대한 제어를 유지할 수 있도록 보장해야 한다.
user program이 무한 루프에 빠지거나 시스템 서비스 호출에 실패해서 제어가 OS에 복귀하지 않은 경우가 없도록 방지해야 한다.

이를 위해서 타이머(timer)를 사용할 수 있다. 타이머는 지정된 시간 후 컴퓨터를 인터럽트 할 수 있다.
가변 타이머는 일반적으로 고정 비율의 클록(fixed-rate clock)계수기로 구현한다.
OS는 여기서 계수기 값을 설정한다. 클록이 똑딱(tick)할 때 마다 계수기가 감소한다. 계수기가 0이 될 때 인터럽트가 발생한다.

ex) 1ms 클록의 10비트 계수기 : 1ms 단위로 1ms ~ 1,024ms(=2^10) 간격을 갖는 인터럽트를 허용

사용자에게 제어를 양도하기 전에 OS는 타이머가 인터럽트할 수 있도록 설정되었는지를 확인한다.
타이머가 인터럽트를 하면 제어는 자동으로 OS에게 넘어간다.
OS는 그러한 인터럽트를 무시하거나 프로그램에게 더 많은 시간을 줄 수 있다.