유저 모드(User mode)
- 개발자가 작성한 코드는 모두 유저 모드에서 실행
- 프로그램 실행 중에 인터럽트(Interrupt)가 발생하거나 시스템 콜(System call)을 호출시에는 커널모드로 전환
커널 모드(Kernel mode)
- 운영 체제의 핵심역할, 시스템 전반을 관리/감독
- 하드웨어와 관련된 작업을 직접 수행
- 프로그램의 현재 CPU 상태를 저장
- 인터럽트나 시스템 콜을 커널 모드에서 직접 처리
- 만약 처리가 완료되면, 중단됐던 프로그램의 CPU 상태를 복원함
- CPU 상태를 복원함과 동시에 통제권을 유저 모드로 반환하여 통제권을 프로그램에게 반환함
- 다시 유저 모드에서는 프로그램이 중단되었던 부분부터 이어서 실행
커널 모드가 존재하는 이유
- 프로그램이 함부로 하드웨어를 점유하게 되면 시스템이 붕괴될 위험이 존재
- 그렇기 때문에 시스템 전반적인 부분이나 하드웨어 같은 부분은 커널 모드에서 관리
- 결국 전체 시스템을 보호하기 위해 고안된 모드
인터럽트(Interrupt)
- 시스템에서 발생한 다양한 종류의 이벤트를 알리는 역할
- 만약 인터럽트가 발생하면, CPU에서 커널 모드에서 해당 커널 코드를 실행
인터럽트의 종류
- 인터럽트의 종류는 매우 많지만, 대표적으로 다음과 같은 것들이 있음
- Power에 문제가 발생 시
- I/O 작업 완료 시
- Timer가 다 됐을 시
- 0으로 나눴을 시
- 유효하지 않은 메모리 공간에 진입했을 시
시스템 콜(System call)
- 프로그램이 OS 커널이 제공하는 서비스를 이용하고 싶을 시, 시스템 콜을 실행
- 만약 시스템 콜이 발생하면, 해당 커널 코드가 커널 모드에서 실행됨
시스템 콜의 종류
- 프로세스 및 스레드 관련 명령어
- 파일 I/O 관련 명령어
- 소켓 관련 명령어
- 장치(Device) 관련 명령어
- 프로세스끼리의 통신 관련 명령어
인터럽트와 시스템 콜의 작동 방식 예제
- 만약 특정 파일을 읽을 때, 프로그램에서는 어떤 방식으로 인터럽트와 시스템 콜이 작동하는지에 대한 가정
- 싱글 코어 CPU에 프로세스에 2개의 스레드가 있다고 가정
- 운영체제의 프로세스 상태에 관한 내용 참조
- 먼저 T1이라는 스레드가 유저 모드에서 실행되고 있다고 가정 (T1: Running 상태, T2: Ready 상태)
- 이후 T1 스레드에서 파일을 읽는 READ라는 시스템 콜을 실행
- 시스템 콜을 실행하면 유저 모드에서 커널 모드로 컨트롤이 넘어감
- T1의 CPU 상태를 저장
- 파일을 READ할 준비
- T1의 Waiting 상태가 되고, Ready 상태에 있는 T2가 스케줄러에 의해 Running 상태가 됨
- 이후 파일을 READ 완료했다는 인터럽트가 발생, 유저 모드에서 커널 모드로 컨트롤이 넘어감
- T2의 CPU 상태를 저장
- 파일 READ를 완료했으니 T1이 Waiting 상태에서 Ready 상태로 변경
- T2의 CPU 상태를 복원하고 다시 T2를 실행
- T2가 진행되고 CPU의 Time-Slice 시간이 다 되면, 하드웨어의 Timer 인터럽트가 발생
- T2의 CPU 상태를 저장
- T2는 주어진 Time-Slice를 다 사용했으니, Ready 상태가 되고, T1은 Running 상태로 전환
- T1의 CPU 상태를 복원하고, 파일을 불러온 지점부터 다시 T1을 실행