9.1 기본 원리: 제한적 직접 실행 (Limited Direct Execution)

기본 개념
- 제한적 직접 실행(Limited Direct Execution)은 프로그램을 CPU에서 직접 실행하여 최대 성능을 달성하려는 기법입니다.
- 직접 실행의 과정:
- 운영체제가 프로세스 항목을 생성.
- 프로그램에 메모리를 할당.
- 프로그램 코드를 디스크에서 메모리로 로드.
- 실행 시작 지점(예:
main() 루틴)으로 분기하여 사용자 프로그램을 실행.
문제점
-
운영체제의 제어 부족:
- 프로그램이 운영체제가 원하지 않는 작업(예: 허가되지 않은 메모리 접근)을 수행할 수 있음.
- 제어가 부족하면 운영체제가 단순한 라이브러리에 불과하게 되어, 운영체제 역할을 수행할 수 없음.
-
CPU 가상화 문제:
- CPU를 하나의 프로세스에 계속 할당하면 다른 프로세스가 실행되지 못함.
- 시분할(Time Sharing) 기법이 필요:
- 프로그램 실행을 중단하고 다른 프로세스로 전환하는 방법이 필요.

9.2 문제점 1: 제한된 연산
문제 정의
- 직접 실행의 한계:
- 사용자 프로그램이 디스크 I/O 요청, 메모리 할당, CPU 자원 요청 등 특수한 연산을 수행하려고 하면 문제가 발생.
- 운영체제가 이러한 요청을 제어하지 못하면 시스템의 보안과 안정성이 위협받음.
- 예: 프로세스가 디스크에 마음대로 접근하면 권한 검사가 무의미해짐.
제한적 연산을 위한 해결책

1. 사용자 모드(User Mode)와 커널 모드(Kernel Mode)
-
사용자 모드(User Mode):
- 프로그램이 제한된 명령어만 실행 가능.
- 특권 명령어(Privileged Instructions) 실행 불가.
- 예: 디스크 I/O, 메모리 접근 등의 특권 작업 수행 불가.
- 특권 작업을 요청하면 트랩(trap)이 발생하고, 운영체제가 제어권을 획득.
-
커널 모드(Kernel Mode):
- 운영체제가 실행되는 모드로, 모든 명령어 실행 가능.
- 시스템 자원 제어 및 특수 작업 수행.
2. 시스템 콜(System Call)
-
시스템 콜:
- 사용자 프로그램이 특권 작업(파일 시스템 접근, 프로세스 생성 등)을 요청하기 위한 메커니즘.
- 프로그램은 trap 명령어를 통해 커널에 진입.
- 운영체제가 요청을 처리한 후, return-from-trap 명령어를 통해 사용자 프로그램으로 복귀.
-
동작 과정:
- 프로그램이 trap 명령어를 호출.
- CPU가 사용자 모드 → 커널 모드로 전환.
- 커널이 요청된 작업을 처리.
- return-from-trap 명령어로 커널 모드 → 사용자 모드로 복귀.
3. 트랩 테이블(Trap Table)
-
트랩 테이블:
- 커널이 하드웨어에 특정 상황(시스템 콜, 인터럽트 등)에서 실행할 코드의 위치를 알려주는 구조.
- 예:
- 디스크 I/O 요청: 디스크 드라이버로 분기.
- 키보드 입력: 키보드 핸들러로 분기.
- 시스템 콜: 시스템 콜 핸들러로 분기.
-
설정 방법:
- 운영체제가 부팅 시 커널 모드에서 트랩 테이블을 초기화.
- 하드웨어에 트랩 테이블 위치를 알려줌.
- 사용자 모드에서 트랩 테이블 변경 시도를 차단(특권 명령어로 보호).
LDE 프로토콜(Limited Direct Execution Protocol)
-
초기화 단계 (부팅 시):
- 운영체제가 트랩 테이블 설정.
- CPU가 테이블 위치를 기억하고 특권 명령어를 보호.
-
프로세스 실행 단계:
- 프로세스 실행:
- 운영체제가 프로세스를 사용자 모드에서 실행 시작.
return-from-trap 명령어로 사용자 모드로 전환.
- 시스템 콜:
- 프로세스가 특권 작업 요청 시 trap 발생.
- 커널 모드에서 작업 처리 후 사용자 모드로 복귀.
- 프로세스 종료:
- 프로그램이
exit() 호출 시 다시 trap 발생.
- 운영체제가 정리 작업 후 프로세스 종료.
장점과 한계
장점
- 사용자 프로그램은 제한된 권한으로 실행되어 안정성과 보안 보장.
- 운영체제가 시스템 자원을 제어하며 효율적인 CPU 가상화 가능.
한계
- 시스템 콜과 컨텍스트 전환에는 오버헤드가 발생.
- 트랩 테이블이 손상되면 시스템 안정성에 심각한 문제가 발생 가능.
9.3 문제점 2: 프로세스 간 전환
문제 정의
- 프로세스 간 전환은 운영체제가 CPU를 특정 프로세스에서 다른 프로세스로 전환하는 작업.
- 하지만 실행 중인 프로세스는 CPU를 점유하고 있으므로, 운영체제는 직접 실행 중이 아니어서 제어권을 얻기 어렵다.
해결 방법
1. 협조적 방식 (Cooperative Scheduling)
- 프로세스가 스스로 CPU를 포기하여 운영체제에 제어를 넘긴다는 가정.
- 주로 시스템 콜을 호출하거나 불법적인 연산(예: 0으로 나누기) 발생 시 제어권이 운영체제로 넘어감.
- 문제점:
- 프로세스가 의도적으로 또는 실수로 시스템 콜을 호출하지 않으면 제어권을 운영체제로 넘기지 않을 수 있음.
- 이런 경우 운영체제는 더 이상 개입할 수 없으며, 컴퓨터를 재부팅해야 하는 상황이 발생할 수 있음.
2. 비협조적 방식 (Preemptive Scheduling)
- 타이머 인터럽트를 이용하여 강제로 CPU 제어권을 운영체제가 획득.
- 일정 주기로 발생하는 타이머 인터럽트를 통해 프로세스 실행을 중단하고 운영체제가 개입.
- 타이머 인터럽트 설정은 부팅 시 운영체제가 설정하며, 인터럽트가 발생하면 미리 등록된 인터럽트 핸들러가 실행됨.
3. 문맥 교환 (Context Switch)
- 운영체제가 프로세스를 전환할 때 실행되는 작업.
- 주요 단계:
- 현재 실행 중인 프로세스의 레지스터 값과 프로그램 카운터(PC)를 커널 스택이나 프로세스 구조체에 저장.
- 전환할 프로세스의 레지스터와 PC를 복원.
- 스택 포인터를 전환하여 새 프로세스의 커널 스택을 활성화.
- return-from-trap 명령어를 호출하여 새 프로세스를 실행.
문맥 교환 과정
- 첫 번째 저장/복원:
- 타이머 인터럽트 발생 시 하드웨어가 실행 중인 프로세스의 사용자 레지스터를 자동으로 커널 스택에 저장.
- 두 번째 저장/복원:
- 운영체제가 결정하여 A 프로세스에서 B 프로세스로 전환 시, 커널 레지스터를 A의 프로세스 구조체에 저장하고 B의 구조체에서 복원.
9.4 병행성이 걱정
문제 정의
- 시스템 콜을 처리하는 도중에 타이머 인터럽트가 발생하거나, 하나의 인터럽트를 처리하는 동안 또 다른 인터럽트가 발생하면 병행성 문제가 발생할 수 있음.
- 운영체제는 이러한 상황에서 데이터 손상이나 비정상적인 동작을 방지해야 함.
운영체제의 대응 방법
1. 인터럽트 불능화 (Interrupt Disabling)
- 원리:
- 특정 인터럽트를 처리하는 동안, 다른 인터럽트를 임시로 차단.
- 차단된 인터럽트는 처리가 완료된 후 재활성화.
- 장점:
- 병행성 문제를 단순화하며, 특정 인터럽트 처리 중 다른 인터럽트가 개입하는 것을 방지.
- 단점:
- 인터럽트를 너무 오래 차단하면, 중요한 인터럽트가 누락될 가능성이 있음.
- 시스템 응답성이 저하될 수 있음.
2. 락(Lock) 기법
- 원리:
- 공유 데이터나 공유 자원에 동시에 접근하지 못하도록 잠금을 설정.
- 하나의 작업이 자원을 사용하는 동안 다른 작업은 대기.
- 장점:
- 커널 내부에서 동시에 여러 작업이 수행될 수 있도록 허용.
- 데이터 무결성과 동작 안정성을 보장.
- 단점:
- 복잡한 락 구현으로 인해 교착 상태(deadlock), 우선순위 역전(priority inversion) 등 문제가 발생할 가능성.
- 디버깅이 어려운 병렬 버그를 초래할 수 있음.