Limited Direct Execution

yalpalyappap·2020년 12월 15일
1

운영체제

목록 보기
2/20

효과적으로 CPU를 가상화 하려면 어떻게 해야하는가

OS는 동시에 진행되는 것 처럼 보이는 프로세스들을 하나의 물리적인 CPU에서 공유해야 한다.
time sharing을 통해서 이러한 가상화를 달성 할 수 있다.

하지만 2가지 중요한 쟁점이 남아있다.

performance

추가적인 시스템의 overhead없이 어떻게 가상화를 달성할 것인가?

control

CPU에 대한 제어권을 점유하고 있는 동안에 어떻게하면 프로세스를 효율적으로 실행할 것인가?

control은 컴퓨터의 resource를 담당하기 때문에 특히나 중요하다. control없이 프로세스가 영구적으로 실행되어 컴퓨터를 차지하거나, 엑세스하면 안되는 정보에 액세스할 위험도 있을 수 있다.

이 두가지 쟁점을 달성하기 위한 방법으로 Limited Direct Execution이 있다.

Limited Direct Execution

Limited Direct Execution에 대해서 이야기 하기전에 Direct Execution은 무엇인지 알아보자.

Direct Execution

Direct Execution이란 CPU에서 직접적으로 프로그램을 실행하는 것을 의미한다.

위의 흐름을 따라서 진행하는 것이 간단한 Direct Execution이라고 할 수 있다.

그런데 Direct Execution에 따라 프로그램을 실행하면 우리가 원하는 대로 CPU를 가상화 할 수 없다.

  1. 만약 유저가 임의의 포인터로 메모리에 접근을 해서 값을 바꾸는 경우 OS가 이를 어떻게 처리할 것인가?
  2. 무한루프가 돌고있는 프로그램이 있을 때 어떻게 다시 CPU에서 control을 가져올 것인가?

그래서 이를 위한 해결책이 Limited Direct Execution이며 그 내용을 살펴보자.

Restricted Operations

Direct Execution은 CPU에서 바로 실행되어 속도가 빠르다는 장점이 있지만, 만약 디스크에 파일을 I/O한다거나, CPU 또는 메모리에 대한 접근권한을 갖는등의 Restricted Operation이 필요하다면 어떨까?
1. 모든 권한을 다 줄 수도 있다 --> 하지만 모든 디스크, 메모리에 대한 권한이 있다면 시스템을 망가트릴 수도 있음
2. protected control transfer를 활용한다.

  • user mode로 돌아가는 프로그램은 하드웨어에 대한 제한적인 권한을 갖는다.
  • kernel mode로 동작하면 모든 권한을 다 가질 수 있다.

그렇다면 user mode인 상태에서 privileged operation을 원한다면 어떻게 하는가?

이를 위한 해결책이 바로 system call이다.

이러한 system call을 통해 파일시스템에 접근, 프로세스의 생성과 파괴, 다른 프로세스와 통신, 메모리할당등의 제한된 작업을 수행할 수 있다.

system call을 호출할 때 프로그램을 특정한 trap 명령을 수행한다.
이 trap 명령은 user mode에서 kernel mode로의 변경을 하게 해준다. 그 후 제한되었던 operation들을 수행한 후 특정한 return-from-trap명령을 수행해서 kernel mode에서 user mode로 다시 되돌아오게 된다.

그런데 하드웨어에서는 trap 명령을 수행하고 return-from-trap할 때 다시 돌아와야할 메모리 주소가 필요하기 때문에 좀 더 주의가 필요하다.
그래서 x86을 예로들면 kernel stack에 program counter, flag등 여러가지의 register를 push한 후 명령을 수행할 때마다 pop을 해서 최종적으로는 return-from-trap을 수행해서 다시 user program으로 돌아올 수 있도록 한다.

그렇다면 이제 trap 명령이 어떻게 OS안에서 어떤 명령을 수행해야하는지 알 수있는것일까?
이를 위해서 trap table이 부팅시에 설정된다. 이 trap table안에 trap 명령어들이 적혀있어서 OS가 하드웨어에게 특정한 이벤트가 발생했을 때 또는 system call이 호출되었을 때 특정한 함수(trap)를 실행하도록 할 수 있다.

Switching Between Process

이제 Direct execution의 2번째 문제인 프로세스간 switch를 어떻게 할 것인가에 대해서 알아보자.
만약 프로세스가 CPU에서 동작중이라면 CPU는 한번에 한가지의 동작을 수행하기 때문에 그 말은 즉 OS는 동작하고 있지 않다는 말이다. 그렇다면 어떻게 OS가 동작중인 프로세스에서 control을 가져와서 다른 프로세스에 할당할 수 있을까...?

Cooperative Approach: Wait For System Calls

Cooperative Approach에서는 OS가 시스템의 프로세스를 신뢰한다. 따라서 너무 오랫동안 동작하는 프로세스는 control을 포기하는 것으로 OS가 다른 작업을 할 수 있게 한다. 그런데 너무 오랫동안 동작하는 프로세스가 없는 경우가 있을 수 있기 때문에 cooperative approach는 2가지의 상황을 기다린다.
1. system call이 호출될 때 이때 호출되는 system call은 yield system call이라고 불리며 system call을 호출해서 현재 프로세스가 가진 control을 OS에게 양도하는 기능을 한다.
2. illegal한 상황이 발생할 때 OS로 trap을 생성하여 OS가 control을 가질 수 있도록 한다.

그런데 만약 illegal하지 않은 무한루프가 발생하고, system call도 발생하지 않는다면?

Non-Cooperative Approach: The OS Takes Control

하드웨어의 도움없이는 OS가 system call의 거부에서 다시 control을 얻어도 할 수 있는 것이 아무것도 없다.
Cooperative Approach에서는 무한루프같은 문제가 발생했을 때 재부팅말고는 답이없다.
그래서 Non-Cooperative Approach에선 timer interrupt라는 것을 사용한다.

매 ms마다 interrupt를 확인해서 interrupt가 발생하면 interrupt handler를 동작시켜서 OS가 다시 CPU의 control을 가질 수 있도록 한다.
system call에서 발생할 수 있는 문제들 때문에 timer interrupt도 부팅시에 table을 지니고 있다.

Saving and Restoring Context

이제 CPU에 대한 control을 다시 system call을 기다리거나, time interrupt를 통해서 다시 가져올 수 있게되었다.
남은 것은 현재 진행중인 프로세스를 더 진행할 것인지 아니면 중단하고 다른 프로세스를 진행시킬 것인지에 대한 결정을 해야한다.

이에대한 결정은 scheduler가 하게된다.
프로세스를 변경하기로 결정했다면 context switch를 실행한다.

profile
안녕하세요! 개발 공부를 하고있습니다~

0개의 댓글