Parker.Dev

Limited Direct Execution

2024-04-03

개요

  • 운영체제는 여러 작업들이 동시에 실행되는 것 처럼 보이도록 물리적인 CPU를 공유함 (시분할방식)
  • 이러한 가상화 기법을 구현하기 위해서 성능저하, 제어 문제를 해결해야 함

제어를 유지하며 CPU 를 가상화 하는 방법

운영체제는 효율적인 방식으로 CPU를 가상화하지만 시스템에 대한 제어를 잃지는 않음

제한적 직접 실행

  • 프로그램을 빠르게 실행하기 위해 제한적 직접 실행 기법 개발
  • 프로세스 목록에 추가 → 프로그램 메모리 할당, 탑재 → 스택 셋 → main() 실행
  • 운영체제가 원치않은 일을 하지 않는다는 것을 보장할 수 없음
  • 프로그램 실행에 제한을 두지 않으면 운영체제는 어떠한 것도 제어 할 수 없음, 단순 라이브러리일 뿐임.

문제점 1: 제한된 연산

  • 직접 실행의 장점은 빠르게 실행됨, 그러나 특수한 종류의 연산을 수행하기 원할때 문제가 발생할 수 있음
  • 프로세스가 원하는 대로 방치할 수 있는 방안도 있지만, 바람직한 시스템을 구축하는 데에는 방해 요인임.

프로세스는 입출력 연산을 비롯해 다른 제한된 연산을 수행해야 함, 그러나 프로세스는 시스템에 대한 권한이 없기 때문에 다른 연산을 수행 할 수 없음

보호된 제어 양도

  • 하드웨어는 두 가지 실행 모드를 제공해 운영체제를 도움.
  • 사용자 모드 (user mode), 커널 모드 (kernel mode) 두가지로 나눔
  • 커널 모드로 진입하기 위한 trap 명령어와 사용자 모드로 돌아가기 위한 return-from-trap 명령어가 제공됨
  • 운영체제가 하드웨어에게 트랩 테이블의 메모리 주소를 알려주기 위한 명령어도 함께 제공 됨

사용자 모드 & 커널 모드

  • 사용자 모드에서 실행 되는 코드는 할 수 있는 일이 제한 됨
  • 커널 모드는 모든 특수한 명령어를 포함해 원하는 모든 작업을 수행 가능함
  • 사용자 프로세스가 특권 작업의 실행을 요구 할 경우의 문제를 해결하기 위해 시스템 콜을 제공함
  • 시스템 콜을 실행하기 위해 프로그램은 trap 특수 명령어를 실행해야 함
    • 커널 안으로 분기하는 동시에 특권 수준을 커널 모드로 상향 조절함
    • 프로세스가 요청한 작업을 완료후 return-from-trap 특수 명령어를 호출함

Trap 명령어를 수행할 시 주의해야 하는 점

  • 호출한 프로세스의 필요한 레지스터들을 저장해야함
    • return-from-trap 명령어 실행 시 사용자 프로세스로 제대로 리턴할 수 있도록 하기 위해서
  • 커널은 부팅 시에 trap-table 을 만들고 이를 이용해 시스템을 통제함
    • 컴퓨터가 부트될 때는 커널 모드에서 동작하기 때문에 하드웨어를 원하는 대로 제어할 수 있음
    • 운영체제는 특정 명령어를 사용해 하드웨어에게 트랩 핸들러의 위치를 알려줌

시스템 콜

  • 모든 시스템 콜은 자신의 고유 번호를 가짐
  • 사용자 프로그램은 원하는 시스템 콜을 호출하기 위해 해당 시스템 콜 번호를 지정된 위치에 저장
  • 각 시스템 콜의 위치는 운영체제만 알고 있음
    • 시스템 콜 코드의 시작 위치를 사용자 프로그램으로 부터 숨김으로써, 커널 코드의 무분별한 실행을 방지함

문제점 2: 프로세스 간 전환

  • 프로세스 전환은 당연히 간단해야 하지만, 실제로는 매우 까다로운 문제임
  • 프로세스가 실행 중이라는 것은 운영체제는 실행 중이지 않다는 것을 의미함

핵심 질문: CPU를 어떻게 다시 획득할 수 있는가

운영체제는 어떻게 CPU를 다시 획득하여 프로세스를 전환할 수 있는가?

협조 방식 (cooperative)

  • 각 사용자 프로세스가 비정상적인 행동을 하지 않을 것이라고 가정, CPU를 장기간 사용해야 하는 프로세스들은 다른 프로세스들이 CPU를 사용할 수 있도록 주기적으로 CPU를 반납할 것이라고 믿음
  • CPU를 반납하기 위해서 운영체제가 프로세스의 상태, 각 레지스터 값들을 저장해 주어야 함
  • 시스템 콜이 운영체제에게 제어를 넘겨 운영체제가 CPU 를 다른 프로세스에게 할당할 수 있는 기회를 제공.
  • 응용 프로그램이 비정상적인 행위를 하게 되면 운영체제에게 제어가 넘어감
  • 운영체제는 시스템 콜이 호출되기를 기다리거나 불법적인 연산이 일어나기를 대기함

비협조 방식: 운영체제가 제어권 확보

  • 타이머 인터럽트를 이용함

  • 인터럽트가 발생하면 운영체제는 현재 수행 중인 프로세스를 중단시키고 해당 인터럽트에 대한 인터럽트 핸들러를 실행함

  • 운영체제는 인터럽트 발생 시 실행해야 할 코드의 주소를 기록해 두어야 함, 이후에 실행해야 하기 때문에

  • 컴퓨터에서 정의된 각 인터럽트에 대해, 관련 인터럽트 핸들러의 위치를 테이블 형태(Interrupt discriptor table)로 메모리에 초기화 시킴

  • 인터럽트 발생시에는 시스템 콜 호출 과 동일하게, 실행 중이던 프로그램의 상태를 저장함

  • return-from-trap 명렁어가 프로그램을 다시 시작할 수 있도록 하기 위함 (하드웨어적으로 실행됨)

문맥의 저장과 복원

  • 협조적 혹은 비협조적 방식으로 운영체제가 제어권을 다시 획득하면, 현재 실행 중인 프로세스를 계속 실행 할것인지 다른 프로세스로 전환할 것인지를 결정해야함
  • 운영체제의 스케줄러라는 부분에 의해서 내려짐

문맥 교환 (context switch)

  • 현재 실행중인 프로세스의 레지스터 값 저장 → 실행 할 프로세스의 레지스터 값 복원 → 실행
  • 운영체제는 return-from-trap 명령어가 마지막으로 실행될 때 현재 실행중이던 프로세스로 리턴하는 것이 아니라, 다른 프로세스로 리턴하여 실행을 다시 함
  • 이런과정은 실행속도 때문에 주로 어셈블리 코드로 작성됨

병행실행으로 인한 문제

  • 만약 시스템 콜을 처리하는 도중에 타이머 인터럽트가 발생하면?
  • 가장 간단한 해법은 인터럽트를 처리하는 동안에는 다른 인터럽트를 불능화 시키는것

CPU 가상화의 핵심

  • CPU는 최소 두 가지 실행모드를 지원해야함
    • 사용자 모드: 제한적
    • 커널 모드: 제한이 없는
  • 일반적인 프로그램은 유저 모드에서 실행되며 시스템 콜을 사용해 커널로 트랩
  • Trap instruction 은 레지스터의 상태 저장 → 하드웨어 상태를 커널 모드로 변경 → 운영체제의 트랩 테이블 조회
  • 운영체제가 시스템 콜 서비스를 마치면 return-from-trap 을 통해 유저 프로그램으로 돌아감
  • 트랩 테이블은 부팅 시 OS 에 의해 설정되어야 하며 사용자 프로그램에 의해 수정이 불가능 해야 함
  • 프로그램이 실행되면 OS 는 유저 프로그램이 영원히 실행되는 것을 막기 위해 타이머 인터럽틀르 사용함