목차
[아래 표, 그림은 강의자료를 첨부한 내용입니다(About Process) 참고]
Limited Direct Execution
Summary of Last Class
- Time Sharing
- Context switch
- Scheduling policy
- Process State
- Running, Ready, Blocked
Limited Direct Execution
- 운영체제가 프로그램이 실행될 때 계속해서 간섭해야 함
- 이 친구가 잘 돌고 있는가?
- 금지된 거를 실행하고 있는 거 아니야?
- 자원을 독점적으로 쓰는 거 아니야? 와 같은 간섭을 계속함
- Direct Execution
- 뒷짐지고 그냥 방치하는 현상
- 따라서, 위의 제약을 걸기 위해 Limited Direct Execution이 등장
Direct Execution
OS | Program |
Create Entry for process list | |
Allocate memory for program | |
Load program into memory | |
Set up stack with argc/argv | |
Clear registers | |
Execute call main() | |
Run main() | |
Execute return from main() | |
Free memory of process | |
Remove from process list |
- 운영체제가 어떤 프로그램을 실행하려고 할 때
- 뭔가 프로세스가 초기화 이후, 돈 뒤에 종료되는 과정
- process list
- 쉽게 생각하면 지난 시간 생각했던 scheduling queue 중에 ready queue라는 것
- entry를 생성하는 것
- 프로세스 컨트롤 블락(PCB)를 의미 → 하나 생성
- 운영체제는 PCB들을 linked list로 쭉 연결해서 관리함.
- 메모리에 프로그램을 할당하고 load
- 컴파일 하면 executable file이 나옴
- a.out : disk에 저장되어 있음
- cpu는 기본적으로 주소를 가지고 자기가 실행할 인스터럭션을 하나하나 실행시킴
- 이 스토리지라는 것은 주소를 안 가지고 있기 때문에 메모리에 올려줘야 함
- 실행파일을 실행하게 되면 디스크에 있는 내용을 메모리에 카피한다라고 생각하면 됨.
- 프로그램 실행하고 싶다면 disk에서 메모리로 executable file안에 있는 instruction들을 복사해야함.
- stack을 통해서 argc/argv를 전달함
- 시스템이 관리하는 stack. 함수가 호출될 때마다 함수를 위한 local variable, state information을 저장하는 스택임
- 실행해야 되니까 register값들을 초기화 시킨 후에
- main함수 실행하라고 호출
- 프로그램 실행 후 끝나면 리턴
- 사용한 메모리들을 운영체제가 호출해서 수고함.
- PCB 제거
[문제점]
- 프로세스는 하나만 도는 것이 아님
- 여러 놈들이 같이 실행되다 보니까, 프로그램을 실행하고 끝날 때까지 운영체제가 중재할 수 있는 방안이 없음
- 즉, 간섭할 수 있는 방안이 없는 구조인 것.
- 실제로 운영체제는 main 함수를 호출한 뒤에, main함수를 프로그램이 실행하게 된다면 관여할 수 있도록 짜여져 있음
OS | Program |
Execute call main() | |
Run main() | |
Wait!!!!! (Mechanism) |
|
Execute return from main() |
- 간섭하는 과정에선…
OS | Program |
Execute call main() | |
Run main() | |
Let me see if... (Policy) - Restricted operations - Time sharing |
|
Execute return from main() |
- 어떻게 권한을 벗어나지 않으면서 간섭하는지, 어떻게 Time sharing을 하게끔 하는 지 그거에 대한 mechanism을 보자.
Problem #1: Restricted Operations
- 어떻게 restricted operation을 구현하나?
- restricted operation은 privileged operation이라고 불리기도 함
- e.g.1 : I/O request
- e.g.2 : CPU, Memory 자원과 같은 system resource를 요구하는 경우
- 응용 프로그램이 실행되면서 꼭 사용되어야 할 내용들. 즉, 제한되고 있는 환경에서 실행되어야 한다.
- restricted operation은 privileged operation이라고 불리기도 함
- 이제 어떤 방식으로 이를 가능케 하는 지 아래서 살펴보자.
Processor Modes
[CPU가 제공해주는 내용]
- User mode
- Code that runs in user mode is restricted in what it can do
- Level 3
- system call을 사용할 땐 level 0이 된 채로 실행됨.
- Restricted operations would result in the processor raising an exception
- privileged instruction mode를 사용할 수 없음
- Code that runs in user mode is restricted in what it can do
- Kernel mode
- In this mode, code that runs can do what it likes
- OS runs in kernel mode
- privileged instruction mode를 사용할 수 있음
System Calls
- 이를 부르기 위해 사용되는 것이…
- Trap instruction
- 처음에 부팅될 때 하드웨어적으로 이렇게 구성 되어있다… 하고 초기화 됨.
- trap instruction이 호출되었을 때 실행될 코드들, trap handler들의 위치를 알려주는 테이블
- 번호를 명시하도록 되어 있음.
- 프로그래머들이 마음대로 정의한 함수들이 아니고, os 안에서 정의된 함수들로 여러가지 검사를 함.
- 이러한 번호로 호출될 수 있는 것인지 검사를 하고 통과시켜줌
- 시스템 콜을 위한 라이브러리 안을 보면, 시스템 콜 번호를 명시하게 되어있지 어떠어떠한 기능을 수행하라는 지 적혀있는 것은 아님.
- 운영체제에 있는 특정 주소를 접근할 수 있는 것이 아니라, 미리 정해진 번호에 대해서만 서비스(restricted operation)을 호출할 수 있는 것.
- 운영체제가 미리 정의해 놓은 핸들러가 호출되고, 핸들러 안에서는 유저가 합법적으로 호출한 것인지 검사하고 통과되면 실행시켜줌.
- Jumps into the kernel
- process mode를 kernel mode로 상승
- 즉, 권한 상승
- process mode를 kernel mode로 상승
- Raises the privilege level to kernel mode
- Return-from-trap instruction
- Returns into the calling user program
- Reduces the privilege level back to user mode
- 즉, 다시 권한 down
[즉 이것이 안전 보장을 해줄 수 있는가..?]
이를 보장하기 위해 trap instruction은 그냥 임의의 address로 jump한다.
- 커널 안의 함수를 호출할 수 없음

- trap table 앞에 있는 함수들만 부를 수 있음.
- 인덱스로 명시만 할 수 있음
- base address를 하드웨어에게 넘겨준다.
- 몇 번째 코드를 실행해.. 이런 식으로 요청하지 못하고
- 적힌 주소에 대한 함수만 실행시킬 수 있고, 다른 쪽 함수는 부를 수 없음
- 인덱스로 명시만 할 수 있음
- 얘는 운영체제가 초기화 시켜줌
- 운영체제가 스스로 “너는 이러한 게이트를 통해서만 들어올 수 있다“ 라고 정해놓는 것
- trap - table이 임의의 주소 번지를 참조할 수 있다면 os에서 다 막아줘야 하는 상황이 발생하므로..
- kernel mode로 접근해서는 trap-table을 통해서만 함수에 접근할 수 있고, 이를 통해서 안정성을 강화
- e.g : file_descriptor → fd에 임의의 값을 넣고 실행시키면 작동하지 않음.
- 일단은 trap table은 게이트와 같은 역할. trap-table로 게이트를 정의해놓고, gate에서도 여러가지 상황을 고려해야 함.
- 임의의 숫자를 입력한 상황: fd[1004]를 했다고 거기서 write, read를 할 수 없다고 gate를 통해서 fail이라고 반환해주는 상황을 예시로 들 수 있음
OS | Hardware | Program |
Initialize trap table | ||
Remember address of syscall handler |
||
Create entry for process list | ||
Allocate memory for program | ||
Load program into memory | ||
Set up user stack with argc/argv | ||
Fill kernel stack with regs/PC | ||
Return-from-trap | ||
Restore regs from kernel stack | ||
Move to user mode | ||
Jump to main | ||
Run main() | ||
... | ||
Call system call | ||
Trap into OS | ||
Save regs/PC to kernel stack | ||
Move to kernel mode | ||
Jump to trap handler | ||
Handle trap | ||
Return-from-trap | ||
Restore regs from kernel stack | ||
Move to user mode | ||
Jump to PC after trap | ||
Return from main() | ||
Trap(via exit()) | ||
Free memory of process | ||
Remove from process list |
- 구분선 위쪽은 OS가 실행되면서 되는 것
- 파란색: stack과 관련
- 응용 프로그램은 실행되지 않음에도 불구하고 먼저 Return-from-trap을 부름
- user mode를 process mode를 바꾼다.
- loading → main() 순서임
- 노란색 박스: address space
- 가운데 선: user mode, kernel mode를 구분해주는 주소 공간
[main]

- 하얀색 박스: stack
- 즉, 한 프로세스는 스택을 2개 가지고 있음(user, kernel mode)
- PC: Program Counter
- 시스템 콜을 부르게 된다면 trap instruction을 부름
- Trap Handler를 부르게 되고
- kernel mode를 진입
- 적절한 위치로 PC를 이동시킴(by trap handler)
- 유저 쪽에서 실행되던 register, program counter를 kernel stack에 담아줌
- 다시 user-mode로 돌아갔을 때 기존 사용되고 있던 PC로 돌아가기 위해서
- 이후 Return-from-trap을 부르게 된다면 기존 PC가 있던 위치로 복귀
[loading]

- 처음에 user stack에는 아무것도 없음 → load하면서 user stack에 정보가 담기고
- 운영체제가 인위적으로 user stack의 정보를 kernel stack에 넣어줌
- return-from-trap으로 user mode로 넘어가게 되면서 정보들을 user stack에 다 넣어주게 되면서, main 함수부터 실행하게 된다.
Problem #2: Switching Between Processes
- 호출하면 안되는 영역을 접근하려고 하지 않는지?
- 감시 → 적절한 경우 privileged operation을 호출
- 어떤 프로세스가 실행한다는 것은 OS가 꼭 실행한다는 것을 의미하는 게 아님
- 즉, 응용 프로그램이 시스템 콜을 부르지 않으면 OS가 실행되지 않는 다는 건데… 안 불러주는 데 계속 혼자 외롭게 있는가?
Cooperative Approach
운영체제가 CPU 자원을 가져오는 시점은 시스템 콜을 부를 때
- Wait for system calls
- Processes that run for too long are assumed to periodically give up the CPU
- 일반적으로 응용프로그램은 시스템 콜을 자주 부름. 시스템 콜 내부마다 타임 쉐어링을 하기 위한 코드를 넣은 뒤에 해당 관련 작업을 할 수 있도록
- Explicit yield system call
- Processes that run for too long are assumed to periodically give up the CPU
- Wait for errors
- Applications also transfer control to the OS when they do an illegal operation
• Dividing by zero
• Segmentation fault
- Applications also transfer control to the OS when they do an illegal operation
- The OS takes control
- Timer interrupt
- 기본적으로 cpu안에 Timer를 내장함
- 중간중간에 한 번씩 점검
- Timer interrupt
Context Switch
- Saving and restoring context (내부적으로 현재 실행하고 있는 프로세스의 context를 저장하고, 실행하고자 하는 프로세스의 context로 환원해주는 일)
- Save a few register values for the currently-executing process(onto its kernel stack)
- Restore a few for the soon-to-be-executing process (from its kernel stack)
- Ensures that when the return-from-trap instruction is finally executed, the system resumes execution of another process
- 새로 실행될 프로세스로 돌아갈 때도, return-from-trap instruction을 사용하도록 함
E.g

- Timer interrupt는 기본적으로 trap handler와 동일한 처리를 함
- user stack info → kernel stack
- Timer interrupt는 일반적으로 CPU 스케쥴링, 즉 Time Sharing을 구현하기 위한 기법들을 포함하고 잇음
- 프로세스 A가 지금까지 실행된 내역들을 보고 프로세스 B 쪽으로 Context switch를 할까말까 결정함
- interrupt handler → cpu에 의해서 호출된 함수이고, 그 함수는 그 때 당시에 실행되고 있던 프로세스의 context에 기생해서 실행하게 된다. 그래서 현재는 interrupt handler가 불려진 이후 interrupt handler, cpu - scheduling가 실행하던 context 정보를 저장함
Stacks in Limited Direct Execution


반응형
'University > 운영체제' 카테고리의 다른 글
Process (1) | 2024.03.06 |
---|
[아래 표, 그림은 강의자료를 첨부한 내용입니다(About Process) 참고]
Limited Direct Execution
Summary of Last Class
- Time Sharing
- Context switch
- Scheduling policy
- Process State
- Running, Ready, Blocked
Limited Direct Execution
- 운영체제가 프로그램이 실행될 때 계속해서 간섭해야 함
- 이 친구가 잘 돌고 있는가?
- 금지된 거를 실행하고 있는 거 아니야?
- 자원을 독점적으로 쓰는 거 아니야? 와 같은 간섭을 계속함
- Direct Execution
- 뒷짐지고 그냥 방치하는 현상
- 따라서, 위의 제약을 걸기 위해 Limited Direct Execution이 등장
Direct Execution
OS | Program |
Create Entry for process list | |
Allocate memory for program | |
Load program into memory | |
Set up stack with argc/argv | |
Clear registers | |
Execute call main() | |
Run main() | |
Execute return from main() | |
Free memory of process | |
Remove from process list |
- 운영체제가 어떤 프로그램을 실행하려고 할 때
- 뭔가 프로세스가 초기화 이후, 돈 뒤에 종료되는 과정
- process list
- 쉽게 생각하면 지난 시간 생각했던 scheduling queue 중에 ready queue라는 것
- entry를 생성하는 것
- 프로세스 컨트롤 블락(PCB)를 의미 → 하나 생성
- 운영체제는 PCB들을 linked list로 쭉 연결해서 관리함.
- 메모리에 프로그램을 할당하고 load
- 컴파일 하면 executable file이 나옴
- a.out : disk에 저장되어 있음
- cpu는 기본적으로 주소를 가지고 자기가 실행할 인스터럭션을 하나하나 실행시킴
- 이 스토리지라는 것은 주소를 안 가지고 있기 때문에 메모리에 올려줘야 함
- 실행파일을 실행하게 되면 디스크에 있는 내용을 메모리에 카피한다라고 생각하면 됨.
- 프로그램 실행하고 싶다면 disk에서 메모리로 executable file안에 있는 instruction들을 복사해야함.
- stack을 통해서 argc/argv를 전달함
- 시스템이 관리하는 stack. 함수가 호출될 때마다 함수를 위한 local variable, state information을 저장하는 스택임
- 실행해야 되니까 register값들을 초기화 시킨 후에
- main함수 실행하라고 호출
- 프로그램 실행 후 끝나면 리턴
- 사용한 메모리들을 운영체제가 호출해서 수고함.
- PCB 제거
[문제점]
- 프로세스는 하나만 도는 것이 아님
- 여러 놈들이 같이 실행되다 보니까, 프로그램을 실행하고 끝날 때까지 운영체제가 중재할 수 있는 방안이 없음
- 즉, 간섭할 수 있는 방안이 없는 구조인 것.
- 실제로 운영체제는 main 함수를 호출한 뒤에, main함수를 프로그램이 실행하게 된다면 관여할 수 있도록 짜여져 있음
OS | Program |
Execute call main() | |
Run main() | |
Wait!!!!! (Mechanism) |
|
Execute return from main() |
- 간섭하는 과정에선…
OS | Program |
Execute call main() | |
Run main() | |
Let me see if... (Policy) - Restricted operations - Time sharing |
|
Execute return from main() |
- 어떻게 권한을 벗어나지 않으면서 간섭하는지, 어떻게 Time sharing을 하게끔 하는 지 그거에 대한 mechanism을 보자.
Problem #1: Restricted Operations
- 어떻게 restricted operation을 구현하나?
- restricted operation은 privileged operation이라고 불리기도 함
- e.g.1 : I/O request
- e.g.2 : CPU, Memory 자원과 같은 system resource를 요구하는 경우
- 응용 프로그램이 실행되면서 꼭 사용되어야 할 내용들. 즉, 제한되고 있는 환경에서 실행되어야 한다.
- restricted operation은 privileged operation이라고 불리기도 함
- 이제 어떤 방식으로 이를 가능케 하는 지 아래서 살펴보자.
Processor Modes
[CPU가 제공해주는 내용]
- User mode
- Code that runs in user mode is restricted in what it can do
- Level 3
- system call을 사용할 땐 level 0이 된 채로 실행됨.
- Restricted operations would result in the processor raising an exception
- privileged instruction mode를 사용할 수 없음
- Code that runs in user mode is restricted in what it can do
- Kernel mode
- In this mode, code that runs can do what it likes
- OS runs in kernel mode
- privileged instruction mode를 사용할 수 있음
System Calls
- 이를 부르기 위해 사용되는 것이…
- Trap instruction
- 처음에 부팅될 때 하드웨어적으로 이렇게 구성 되어있다… 하고 초기화 됨.
- trap instruction이 호출되었을 때 실행될 코드들, trap handler들의 위치를 알려주는 테이블
- 번호를 명시하도록 되어 있음.
- 프로그래머들이 마음대로 정의한 함수들이 아니고, os 안에서 정의된 함수들로 여러가지 검사를 함.
- 이러한 번호로 호출될 수 있는 것인지 검사를 하고 통과시켜줌
- 시스템 콜을 위한 라이브러리 안을 보면, 시스템 콜 번호를 명시하게 되어있지 어떠어떠한 기능을 수행하라는 지 적혀있는 것은 아님.
- 운영체제에 있는 특정 주소를 접근할 수 있는 것이 아니라, 미리 정해진 번호에 대해서만 서비스(restricted operation)을 호출할 수 있는 것.
- 운영체제가 미리 정의해 놓은 핸들러가 호출되고, 핸들러 안에서는 유저가 합법적으로 호출한 것인지 검사하고 통과되면 실행시켜줌.
- Jumps into the kernel
- process mode를 kernel mode로 상승
- 즉, 권한 상승
- process mode를 kernel mode로 상승
- Raises the privilege level to kernel mode
- Return-from-trap instruction
- Returns into the calling user program
- Reduces the privilege level back to user mode
- 즉, 다시 권한 down
[즉 이것이 안전 보장을 해줄 수 있는가..?]
이를 보장하기 위해 trap instruction은 그냥 임의의 address로 jump한다.
- 커널 안의 함수를 호출할 수 없음

- trap table 앞에 있는 함수들만 부를 수 있음.
- 인덱스로 명시만 할 수 있음
- base address를 하드웨어에게 넘겨준다.
- 몇 번째 코드를 실행해.. 이런 식으로 요청하지 못하고
- 적힌 주소에 대한 함수만 실행시킬 수 있고, 다른 쪽 함수는 부를 수 없음
- 인덱스로 명시만 할 수 있음
- 얘는 운영체제가 초기화 시켜줌
- 운영체제가 스스로 “너는 이러한 게이트를 통해서만 들어올 수 있다“ 라고 정해놓는 것
- trap - table이 임의의 주소 번지를 참조할 수 있다면 os에서 다 막아줘야 하는 상황이 발생하므로..
- kernel mode로 접근해서는 trap-table을 통해서만 함수에 접근할 수 있고, 이를 통해서 안정성을 강화
- e.g : file_descriptor → fd에 임의의 값을 넣고 실행시키면 작동하지 않음.
- 일단은 trap table은 게이트와 같은 역할. trap-table로 게이트를 정의해놓고, gate에서도 여러가지 상황을 고려해야 함.
- 임의의 숫자를 입력한 상황: fd[1004]를 했다고 거기서 write, read를 할 수 없다고 gate를 통해서 fail이라고 반환해주는 상황을 예시로 들 수 있음
OS | Hardware | Program |
Initialize trap table | ||
Remember address of syscall handler |
||
Create entry for process list | ||
Allocate memory for program | ||
Load program into memory | ||
Set up user stack with argc/argv | ||
Fill kernel stack with regs/PC | ||
Return-from-trap | ||
Restore regs from kernel stack | ||
Move to user mode | ||
Jump to main | ||
Run main() | ||
... | ||
Call system call | ||
Trap into OS | ||
Save regs/PC to kernel stack | ||
Move to kernel mode | ||
Jump to trap handler | ||
Handle trap | ||
Return-from-trap | ||
Restore regs from kernel stack | ||
Move to user mode | ||
Jump to PC after trap | ||
Return from main() | ||
Trap(via exit()) | ||
Free memory of process | ||
Remove from process list |
- 구분선 위쪽은 OS가 실행되면서 되는 것
- 파란색: stack과 관련
- 응용 프로그램은 실행되지 않음에도 불구하고 먼저 Return-from-trap을 부름
- user mode를 process mode를 바꾼다.
- loading → main() 순서임
- 노란색 박스: address space
- 가운데 선: user mode, kernel mode를 구분해주는 주소 공간
[main]

- 하얀색 박스: stack
- 즉, 한 프로세스는 스택을 2개 가지고 있음(user, kernel mode)
- PC: Program Counter
- 시스템 콜을 부르게 된다면 trap instruction을 부름
- Trap Handler를 부르게 되고
- kernel mode를 진입
- 적절한 위치로 PC를 이동시킴(by trap handler)
- 유저 쪽에서 실행되던 register, program counter를 kernel stack에 담아줌
- 다시 user-mode로 돌아갔을 때 기존 사용되고 있던 PC로 돌아가기 위해서
- 이후 Return-from-trap을 부르게 된다면 기존 PC가 있던 위치로 복귀
[loading]

- 처음에 user stack에는 아무것도 없음 → load하면서 user stack에 정보가 담기고
- 운영체제가 인위적으로 user stack의 정보를 kernel stack에 넣어줌
- return-from-trap으로 user mode로 넘어가게 되면서 정보들을 user stack에 다 넣어주게 되면서, main 함수부터 실행하게 된다.
Problem #2: Switching Between Processes
- 호출하면 안되는 영역을 접근하려고 하지 않는지?
- 감시 → 적절한 경우 privileged operation을 호출
- 어떤 프로세스가 실행한다는 것은 OS가 꼭 실행한다는 것을 의미하는 게 아님
- 즉, 응용 프로그램이 시스템 콜을 부르지 않으면 OS가 실행되지 않는 다는 건데… 안 불러주는 데 계속 혼자 외롭게 있는가?
Cooperative Approach
운영체제가 CPU 자원을 가져오는 시점은 시스템 콜을 부를 때
- Wait for system calls
- Processes that run for too long are assumed to periodically give up the CPU
- 일반적으로 응용프로그램은 시스템 콜을 자주 부름. 시스템 콜 내부마다 타임 쉐어링을 하기 위한 코드를 넣은 뒤에 해당 관련 작업을 할 수 있도록
- Explicit yield system call
- Processes that run for too long are assumed to periodically give up the CPU
- Wait for errors
- Applications also transfer control to the OS when they do an illegal operation
• Dividing by zero
• Segmentation fault
- Applications also transfer control to the OS when they do an illegal operation
- The OS takes control
- Timer interrupt
- 기본적으로 cpu안에 Timer를 내장함
- 중간중간에 한 번씩 점검
- Timer interrupt
Context Switch
- Saving and restoring context (내부적으로 현재 실행하고 있는 프로세스의 context를 저장하고, 실행하고자 하는 프로세스의 context로 환원해주는 일)
- Save a few register values for the currently-executing process(onto its kernel stack)
- Restore a few for the soon-to-be-executing process (from its kernel stack)
- Ensures that when the return-from-trap instruction is finally executed, the system resumes execution of another process
- 새로 실행될 프로세스로 돌아갈 때도, return-from-trap instruction을 사용하도록 함
E.g

- Timer interrupt는 기본적으로 trap handler와 동일한 처리를 함
- user stack info → kernel stack
- Timer interrupt는 일반적으로 CPU 스케쥴링, 즉 Time Sharing을 구현하기 위한 기법들을 포함하고 잇음
- 프로세스 A가 지금까지 실행된 내역들을 보고 프로세스 B 쪽으로 Context switch를 할까말까 결정함
- interrupt handler → cpu에 의해서 호출된 함수이고, 그 함수는 그 때 당시에 실행되고 있던 프로세스의 context에 기생해서 실행하게 된다. 그래서 현재는 interrupt handler가 불려진 이후 interrupt handler, cpu - scheduling가 실행하던 context 정보를 저장함
Stacks in Limited Direct Execution


반응형
'University > 운영체제' 카테고리의 다른 글
Process (1) | 2024.03.06 |
---|