Performance : context switching overhead를 고려하여 어떻게 virtualize?
Control : process를 실행하면서 CPU에 대한 control을 OS가 어떻게 가져올까?
Just run the program directly on the CPU
6->7에서 CPU control : OS -> process
8->9에서 CPU control : process -> OS
Direct Execution에서는 program 실행에 limit가 없다.
OS는 program 실행 중에 어떤 것도 control 할 수 없는 "Just a Library"
Process가 실행될 때 OS의 제약을 받지 않기 때문에 실행 속도가 빠르긴 하지만
restricted operation을 실행하여 system에 문제가 생길 수도 있다
- disk에 I/O request
- 할당된 resource를 초과해서 접근
Solution : Using protected control transfer
- User mode (bit=0) : program이 실행될 때의 mode, application에서 full access 불가능
- Kernel mode (bit=1) : OS가 full access 가능
privilege level : User mode < kernel mode
Process가 실행 도중 OS에게 특정 작업에 대한 요청(System call, interrupt)를 하고 OS는 이 요청이 타당한 지 확인 후 수행한다.
application이 kernel(OS)에게 특정 기능을 수행하도록 요청하는 작업
Example =>
Accessing the file system
Creating and destroying processes
Communicating with other processes
Allocating more memory
user mode에서 실행되는 application이 수행할 수 없는 작업을 위해
OS가 제공하는 system call을 호출하면
user mode -> kernel mode로 바뀌고 결과를 application에게 반환 후
kernel mode -> user mode로 바뀌고 system call 이후 코드가 실행된다.
- Trap Instruction
Jump into the kernel
Raise the privilege level to kernel mode
- Return-from-trap instruction
Return into the calling user program
Reduce the privilege level back to user mode
-> Trap instruction이 실행되면 Trap table의 특정 위치로 jump
-> trap table에 적힌 주소로 jump하여 system call handler 실행
-> return-from-trap을 실행하고 돌아옴
process가 실행되고 있을 땐 CPU에 대한 control을 뺏긴 상황,
process를 switch하려면 CPU에 대한 control을 OS가 가지고 있어야 하는데 어떻게 가져올까?
- Cooperative Approach : Wait for system call
- Non-Cooperative Approach : OS takes control by timer interrupt
process가 yield 같은 system call 혹은 execption 을 만들어 CPU의 cotrol을 OS로 넘겨준다.
1. process -> system call -> OS
2. proces -> execption -> OS
Problem : system call이나 execption이 등장하기 전에 infinite loop에 빠지는 경우
-> Reboot를 제외하고 해결 방법이 없다.
timer가 CPU에 주기적으로 timer interrupt를 보낸다.
interrupt를 감지하면
-> process를 멈추고, register 값을 kernel stack에 저장하고, kernel mode로 바꾼 후
-> trap table로 jump, interrupt handler 실행
-> scheduling(switching).. 다른 process 실행
- 현재 A process의 register 값을 PCB(A)에 저장한다.
- 새로 실행할 B process의 PCB(B)에 저장된 값을 register로 복원한다.
- kernel stack을 A->B로 바꾼다.