[OSTEP] Mechanism: Limited Direct Execution (LDE protocol)

Mechanism Design goals

• Performance

과도한 overhead로 인한 performance 손실없이 virtualization을 구현

• Control

CPU에 대한 control을 유지하면서 프로세스를 효율적으로 실행

Limited Direct Execution

• Direct Execution

프로그램을 가능한 빠르게 작동하게 하기위해 OS는 프로그램 실행의 전처리 과정만 수행후, cpu에서 프로그램을 직접 실행하도록함
부팅과 런타임, 종료시 아래 그림과 같은 과정을 거친다.
하지만 아래 2가지 문제점 존재

• Bad behavior of process

» Divide User mode and kernel mode

kernel mode에선 I/O requests와 같은 제한된 명령을 수행가능하지만 user mode에서는 그렇지 않다.
이런 분리를 통해 user mode에서 중요한 메모리에 대한 접근 등을 막음(하드웨어는 mode에 따라 resource에 대한 access권한을 다르게 제공)
user mode에서 제한된 명령을 수행하려 할 시 process를 kill한다.

» System call

user mode에서 작동하던 process가 kernel mode에서만 가능한 privileged operation을 할때 system call을 호출

system call 내부의 trap 명령어에 의해서 kernel mode로 전환
secure program을 위해선 system call 에서 호출시 전달되는 인자들을 처리해야 함(위험한 argument 전달시 reject)

system-call number
커널이 가지고 있는 system call function의 시작 주소를 담고있는 Array(배열)의 Index 번호로 사용이 된다.
OS는 trap handler에서 system call을 다룰때 systemcall number이 유효한지 확인후, 코드를 실행한다.

이는 protection의 목적으로 user code는 실행되어야 할 kernel코드의 정확한 주소를 바로 요청할 수 없게하기 위함이다.

↪ system call 읽어보면 좋은글 : https://bit.ly/3mYRS1h

» trap

안정성과 보안상의 이유로 OS는 trap 명령 직후 바로 kernel상의 코드가 위치한 주소를 알려주지 않음

trap table
boot time에서 kernel mode에서 hardware에게 trap table 을 setting하여 exceptional events가 발생시 어디에 있는 코드(이를 trap handler라고 함)를 실행해야 할지 알려줌

• Process switch

CPU에서 process를 direct execution하면 OS는 실행 중이 아니라는 것이므로 OS는 process switch를 하는데 특별한 방법이 필요함

» Cooperative

초기 시스템에서 채택되었던 방식, 운영체제가 프로세스들이 합리적으로 작동할 것이라고 신뢰함

프로세스에서 시스템콜을 호출해 자발적으로 OS에게 CPU제어권을 넘겨줌
(yield system call)
어떤수를 0으로 나누거나 접근할 수 없는 메모리에 접근하는등 비정상적인 행위를 하면 운영체제로의 trap이 일어남, OS는 CPU를 점유해 프로세스를 종료가능
하지만 프로세스가 무한루프 등에 빠져 시스템콜을 호출할 수 없을때 대처방법이 없음

» Non cooperative

cooperative방식의 문제점을 보완하기 위해 timer interrupt를 발명

Timer interrupt
수 mili second마다 인터럽트를 발생, 인터럽트 시 현재 수행중인 프로세스는 중단되고 운영체제의 interrupt handler가 실행됨

운영체제는 하드웨어에게 interrupt 발생시 실행할 코드를 부팅될 때 미리 알려줌, 부팅과정 중 타이머를 시작

부팅후 인터럽트 발생시 시스템콜과 유사하게 커널스택에 프로그램의 상태(레지스터 등)를 저장후 나중에 return-from-trap으로 다시시작하게 함

타이머는 특정명령어를 통해 끄는것이 가능

» Context switch

타이머 인터럽트 발생 시,
하드웨어는 현재 프로세스의 커널스택에 사용자 레지스터를 저장함

scheduler에 의해 프로세스를 바꾸기로 결정하면
운영체제는 switch()루틴을 호출
» 커널레지스터를 해당 프로세스의 proc구조체에 저장
(어셈블리어를 통해) 현재 프로세스의 각종 레지스터, PC, 커널 스택 포인터를 저장하고 다음에 실행될 프로세스의 레지스터, PC, 커널 스택 포인터를 복원함. return-from-trap을 통해 다른 프로세스로 전환됨

아래 그림은 해당 과정을 나타냄

병행성 문제
인터럽트를 처리하는동안 인터럽트를 불능화 한다.
다만 너무 오랫동안 인터럽트를 불능화 하는것은 바람직하지 않음

또한, 운영체제는 내부 자료구조에 동시에 접근하는것을 방지하기 위해 lock기법을 개발해, 커널안에서 여러 활동이 진행될 수 있게 허용함

Homework

• System call 측정

#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>

void main(void)
{
	struct	timeval time;
	long int t;
	char	buf[100];
 	int	i = 0;
	int	sum = 0;
	int fd = open("./fortest", O_RDWR);
    
	for(int k = 0 ; k < 100; k++)
	{
		gettimeofday(&time,NULL);
		t = time.tv_sec;
		for(i = 0;t == time.tv_sec; i++)
		{
			read(fd,buf,0);
			gettimeofday(&time,NULL);
		}
		printf("%d\n", i);
		sum+=i;
	}
	printf("average : %d\n",sum/100);
	//the average was 10939602/sec 
}

Related Knowledge

• Kernel stack

Each process has a kernel stack where registers(including general purpose registers and the programcounter) are
saved to and restored from (by the hardware) when transitioning into and out of the kernel.

• PC (Program Counter)

프로그램 계수기, 다음 실행할 명령어의 주소를 저장

• OS와 CPU

운영체제의 많은 연산들은 주로 메모리를 접근하는 연산이며, CPU는 프로세서 속도는 극적으로 발전했으나 대역폭은 그렇지 못하다
CPU가 좋더라도 운영체제의 속도향상은 기대에 못미칠 수도 있다.

좋은 웹페이지 즐겨찾기