[OSTEP] Virtualization) 6. Direct Execution

0

OSTEP 운영체제

목록 보기
3/19
post-thumbnail

[OSTEP] 6. Direct Execution

이 포스팅은 <<Operating Systems: Three Easy Pieces>>, Remzi H. Arpaci-Dusseau & Andrea C. Arpaci-Dusseau을 읽고 개인 학습용으로 정리한 글입니다.

CH 9. 제한적 직접 실행 원리

  • 성능 저하 문제: 시스템에 과중한 오버헤드를 주지 않으면서 가상화를 구현할 수 있을까?

  • 제어 문제: CPU에 대한 통제를 유지하면서 프로세스를 효율적으로 실행시킬 수 있는 방법은 무엇인가?
    -> 제어권을 상실하면 한 프로세스가 영원히 실행을 계속할 수 있음
    -> 제어권을 상실하면 한 프로세스가 접근해서는 안되는 정보에 접근하게 됨

1. 기본 원리: 제한적 직접 실행

  • 제한적 직접 실행(Limited Execution)

직접 실행

  • 프로그램을 CPU 상에서 그냥 직접 실행 시킴

  • 운영체제가 프로그램을 실행하기 시작할 때
    -> 프로세스 목록에 해당 프로세스 항목을 생성
    -> 메모리 할당
    -> 프로그램 코드를 디스크에 탑재
    -> 진입점(ex. main() 루틴)을 찾아 그 지점으로 분기
    -> 사용자 코드 실행 시작

  • 직접 실행의 장점: 빠르게 실행된다
    -> 기본적으로 프로그램이 하드웨어 CPU에서 실행되기 때문

직접 실행의 문제점

  • 프로그램이 운영체제가 원치않는 일을 하지 않는 다는 것을 보장할 수 없다

  • 프로세스 실행 시 운영체제가 프로그램의 실행을 중단하고 다른 프로세스로 전환시킬 수 없다
    -> CPU를 가상화하기 위한 시분할 기법 구현 X

2. 문제점 1: 제한된 연산

  • 만일 프로세스가 특수한 종류의 연산을 수행하길 원한다면 어떨게 될 것인가?

  • 사용자 모드(user mode): 사용자 모드에서 실행되는 코드는 할 수 있는 일이 제한된다
    -> 프로세서가 예외를 발생시키고, 운영체제는 해당 프로세스를 제거한다

  • 커널 모드(kernel mode): 커널 모드에서 실행되는 코드는 모든 특수한 명령어를 포함하여 원하는 모든 작업을 수행할 수 있다
    -> 운영체제의 중요한 코드들이 커널 모드에서 실행됨
    -> ex. 파일 시스템 접근, 프로세스 생성 및 제거, 다른 프로세스와의 통신, 메모리 할당, ...

  • 사용자 프로세스가 특권 명령어를 실행해야 할 때는 어떻게 해야 하는가?

  • 시스템 콜: 커널은 시스템 콜을 통하여 자신의 주요 기능을 사용자 프로그램에게 제공

trap, return-from-trap

  • 시스템 콜을 실행하기 위해 프로그램은 trap 특수 명령어 실행
    -> 커널 안으로 분기 & 특권 수준을 커널 모드로 상향 조정

  • 완료되면 운영체제는 return-from-trap 특수 명령어 호출
    -> 특권 수준을 사용자 모드로 다시 하향 조정 & 호출한 사용자 프로그램으로 리턴

커널 스택

  • 하드웨어는 trap 명령어 수행 시, 호출한 프로세스의 필요한 레지스터들을 저장해야 함
    -> 운영체제가 return-from-trap 명령어 실행 시 사용자 프로세스로 제대로 리턴할 수 있도록

  • x86에서는 프로그램 카운터, 플래그와 다른 몇 개의 레지스터들을 각 프로세스의 커널 스택(kernel stack)에 저장
    -> return-from-trap 명령어가 이 값들을 스택에서 pop하여 사용

⚡trap table & trap handler

  • 호출한 프로세스는 커널 내부의 분기할 주소를 명시할 수 없다
    -> trap이 운영체제 코드의 어디를 실행할지 어떻게 알 것인가?

  • 커널은 부팅 시에 트랩 테이블(trap table) 생성
    (컴퓨터가 부트될 때는 커널모드에서 작동하기 때문에 하드웨어를 원하는 대로 제어 가능)

  • 운영체제는 특권 명령어를 사용하여 하드웨어에게 트랩 해들러(trap handler)의 위치를 알려줌

  • 프로세스는 커널 스택을 각자 가지고 있다
    -> 커널 모드로 진입/진출할 때 하드웨어에 의해 프로그램 카운터와 범용 레지스터 등의 레지스터 저장/복원되는 용도로 사용

  • ⚡프로세스가 자신의 할 일을 다 하고 main()에서 리턴할 때 일반적으로 스텁(stub) 코드로 리턴
    -> 스텁 코드가 프로그램을 종료시킬 때 exit() 시스템 콜 호출
    -> 운영체제로 트랩되어 운영체제가 프로세스 정리

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

  • CPU에서 프로세스가 실행 중이라는 것은 운영체제는 실행 중이지 않다는 것을 의미한다
    -> 운영체제는 어떻게 CPU를 다시 획득하여 프로세스를 전환할 수 있는가?

협조 방식: 시스템 콜 기다리기

  • 협조(cooperative) 방식: 운영체제가 프로세스들이 합리적으로 행동할 것이라고 신뢰
    -> 너무 오랫동안 실행할 가능성이 있는 프로세스는 주기적으로 CPU를 포기할 것이라고 가정

  • 우호적인 프로세스는 자주 시스템 콜을 호출하여 CPU의 제어권을 운영체제에게 넘겨줌

  • 이런 유형의 운영체제는 yeild 시스템 콜 제공
    -> 이 시스템 콜은 운영체제에게 제어를 넘겨 운영체제가 다른 프로세스를 실행할 수 있게 함

  • 응용 프로그램이 비정상적인 행위를 하게 되면 운영체제에게 제어가 넘어간다
    (ex. 어떤 수를 0으로 나누는 연산 실행, 접근할 수 없는 메모리 접근 시도, ...)
    -> 운영체제로의 trap 발생
    -> 운영체제가 해당 행위를 하는 프로세스 종료

비협조 방식: 운영체제가 전권을 행사

  • 협조 방식에서 프로세스가 무한 루프에 빠졌을 경우 컴퓨터를 다시 부팅하는 수밖에 없다
    -> 프로세스가 비협조적인 상황에서도 CPU의 제어를 획득하는 방법은 무엇인가?

  • 타이머 인터럽트(timer interrupt): 수 밀리 초마다 인터럽트를 발생시키도록 함
    -> 인터럽트가 발생하면 현재 수행 중인 프로세스 중단 & 미리 구성된 운영체제의 인터럽트 핸들러 실행

  • 부팅 과정 진행 중에 운영체제는 타이머 시작 & 타이머 인터럽트가 발생했을 때 실행해야 할 코드를 하드웨어에게 알려줌

  • ⚡타이머는 특정 명령어를 통해 끌 수도 있다

문맥의 저장과 복원

  • 운영체제가 제어권을 다시 획득하면 현재 실행중인 프로스세를 계쏙 실행할 것인지 다른 프로세스로 전환할 것인지 결정해야 함
    -> 운영체제의 스케쥴러(scheduler)에 의해 결정

  • 다른 프로세스로 전환하기로 결정되면 운영체제는 문맥 교환(context switch)이라고 알려진 코드를 실행

  • 운영체제는 프로세스 전환을 위해 ⚡저수준의 어셈블리 코드 사용
    -> 현재 실행 중인 프로세스의 범용 레지스터, PC, 커널 스택 포인터 저장
    -> 곧 실행 된 프로세스의 범용 레지스터, PC 복원, 커널 스택을 이 프로세스의 커널 스택으로 전환
    -> 운영체제가 마지막으로 return-from-trap 명령어를 실행하면, 곧 실행된 프로세스가 현재 실행 중인 프로세스가 됨

  • 위 과정이 실행되는 동안 두 번의 레지스터 저장/복원이 일어남

  • (1) 타이머 인터럽트가 발생했을 때
    -> 프로세스의 ⚡사용자 레지스터가 하드웨어에 의해 해당 프로세스의 커널 스택에 암묵적으로 저장

  • (2) 운영체제가 프로세스 A -> 프로세스 B로 전환하기로 결정했을 때
    -> 프로세스의 ⚡커널 레지스터가 운영체제에 의해 해당 프로세스의 프로세스 구조체에 저장

xv6 문맥 교환 코드

4. 병행성이 걱정

  • 시스템 콜을 처리하는 도중에 타이머 인터럽트가 발생하면 어떤 일이 생기는가?
    하나으 인터럽트를 처리하고 있을 때 다른 인터럽트가 발생하면 어떤 일이 생기는가?

  • 간단한 해법: 인터럽트를 처리하는 동안 인터럽트 불능화
    -> 하나의 인터럽트가 처리되고 있는 동안 다른 어떤 인터럽트로 cpu에게 전달되지 않는다

  • 락(lock) 기법 개발
    -> 내부 자료 구조에 동시에 접근하는 것 방지
    -> 커널 안에서 동시에 다수의 활동이 진행될 수 있도록 허용

5. 요약

  • 제한적 직접 실행: CPU 가상화를 구현하기 위한 핵심적인 저수준 기법

  • CPU에서 실행하고 싶은 프로그램을 실행시키지만, 운영체제가 CPU를 사용하지 못하더라도 프로세스의 작업을 제한할 수 있도록 하드웨어 셋업

  • 부팅할 때 트랩 핸들러 함수 셋업 & 인터럽트 타이머 시작 & 제한된 모드에서만 프로세스가 실행되도록 함

  • 운영체제는 특별한 연산을 수행할 때, 프로세스가 CPU를 독점할 때, 다른 프로세스로 전환해야 할 때만 개입

profile
Be patient. Everything comes to you in the right moment.

0개의 댓글