How to efficiently virtualize the CPU with control?
운영체제는 물리적인 CPU를 time sharing으로 공유하고 있다.
Issue
- Performance : 오버헤드(지연시간) 없이 어떻게 구현할 것인가
- Control : 어떻게 CPU에 대한 컨트롤을 유지하면서 효율을 좋게 할 수 있을까
Direct Execution
프로그램을 cpu 위에서 직접 돌리는 경우 -> 프로그램이 돌아가는 동안 아무것도 control할 수 없다
결국 Library의 역할만 하게 된다!
Restricted Operation
만약 금지된 동작(더 많은 자원 요구) 등을 process가 하려고 한다면..?
- Solution : Mode를 나누어서 권한을 주었다
- User mode: 접근이 제한되는 모드
- Kernel mode: 모든 자원에 접근할 수 있는 모드
System Call
User mode에서 높은 권한을 요청할 때 System Call을 통해 자원을 할당받는다
- 파일 시스템으로의 접근
- 프로세스를 만들고, 종료하는 것
- 다른 프로세스와의 통신
- 더 많은 메모리 할당 등
Trap instruction : 외부의 event가 발생했을 때, User -> Kernel모드로 바뀌게 됨
Return-from-trap instruction : Trap으로 kernel에 갔다가 다시 user로 돌아옴
어떤 방식으로 작동할까? -> 트랩의 원인을 분석하고, 트랩을 처리하기 위한 Trap handler를 호출해서 작동하게 된다
System Call number : 어떤 system call인지 구분하기 위하여 사용한다.
Switching Between Processes
어떻게 CPU의 제어권을 가져올 것인가?
- cooperative Approach : system call을 기다리기
- non-cooperative Approach : OS가 컨트롤을 뺏어오기
cooperative Approach
프로세스가 자발적으로 CPU를 반납하는 yield()와 같은 명령어를 사용하길 기다린다.
하지만, 무한 루프에 빠지면 CPU를 돌려받을 수가 없었다. 그래서 요즘은 non-cooperative Approach를 사용한다
non-cooperative Approach
주기적으로 interrupt가 발생한다.
- 동작 방식
- 부팅할 때 timer가 실행된다
- timer가 주기적으로 control을 뺏어온다
- interrupt가 발생되면, 실행중인 프로세스를 중단한 뒤, 프로그램의 상태를 저장하고, 인터럽트 핸들러가 실행된다
Context Switch
어셈블리 코드로 되어있다
- 현재 상태를 저장하기 위해 kernel stack에 레지스터 값들을 저장한다
- 다음 실행될 프로세스의 정보를 kerner stack으로부터 복구한다
- kerner stack을 다음 실행될 곳으로 바뀐다
좋은 정보감사핮니다!