💋 유저 모드 VS 커널 모드
✔️ 유저 모드(User Mode)
- 우리가 작성하는 프로그램의 코드를 실행하는 모드
- 직접적으로 하드웨어에 접근 X
- 운영 체제의 지원을 통해 자원에 접근
- 안정성이 높고, 프로그램 간의 간섭을 방지하여 시스템 전반의 안정성을 유지
✔️ 커널 모드(Kernel Mode)
- 운영 체제의 핵심 부분인 커널이 동작하는 모드
- 하드웨어 자원에 직접적으로 접근하고, 시스템 전체의 제어를 담당
- 일반적인 프로그램은 커널 모드에서 직접 실행되지 않고, 유저 모드에서 커널의 서비스를 호출하여 자원을 사용
✔️ 커널 모드가 필요한 이유
개발자가 직접 작성한 코드가 하드웨어에 직접 영향을 주면, 전체 컴퓨터 시스템이 붕괴될 수 있습니다.
시스템을 보호하기 위해서 하드웨어와 관련된 부분은 커널이 담당하고, 개발자가 작성한 프로그램은 커널을 통해서 하드웨어에 접근할 수 있도록 합니다.
- 시스템 안정성 및 신뢰성
- 유저 모드에서 실행되는 프로그램은 하드웨어 자원에 직접 접근하지 않으며, 운영 체제의 커널을 통해 자원에 접근
- 코드의 오류나 비정상적인 동작이 전체 시스템에 영향을 미치지 않고 안정성이 유지
- 보안
- 유저 모드에서 실행되는 응용 프로그램은 특권 명령을 직접 실행할 수 없습니다.
- 악의적인 코드가 시스템에 피해를 줄 가능성이 줄어듭니다.
- 특권 명령은 커널 모드에서만 실행되며, 응용 프로그램은 운영 체제에게 특정 작업을 요청하여 자원을 사용합니다.
- 다중 사용자 환경
- 다중 사용자 운영 체제에서는 여러 사용자가 동시에 시스템을 사용할 수 있어야 합니다.
- 유저 모드는 사용자 간에 간섭이 최소화되도록 하고, 각각의 응용 프로그램이 독립적으로 실행될 수 있도록 지원합니다.
- 운영 체제의 효율적인 관리
- 운영 체제는 커널 모드에서 실행되어 시스템 자원을 효율적으로 관리하고, 여러 응용 프로그램 간의 자원 충돌을 방지합니다.
- 유저 모드에서는 응용 프로그램이 자체적으로 자원을 관리하지 않고, 운영 체제의 지원을 받아 관리합니다.
✔️ 유저 모드 ↔ 커널 모드
진행 과정은 다음과 같습니다.
유저 모드에서 프로그램 실행 중에 interrupt가 발생하거나, system call을 호출하게 되면 커널 모드로 전환됩니다.
커널 모드에서는 이전까지 실행중이던 CPU 상태를 저장합니다.
Interrupt, systeml call을 직접 처리합니다. ⇒ CPU에서 커널 코드가 실행
처리가 완료되면, 다음에 실행할 프로그램을 실행하기 위해 CPU 상태를 복원합니다.
그리고 통제권을 다시 프로그램에게 반환하며, 유저 모드로 전환되고, 다시 프로그램이 실행됩니다.
유저 프로세스와 OS 커널이 소통하는 방식은 system call, interrupt입니다. 각각 알아봅시다!
💋 system call
프로그램이 OS 커널이 제공하는 서비스를 이용하고 싶을 때 system call을 합니다.
커널에 대한 프로그램의 요청이라고 보면 됩니다.
system call이 발생하면, 그 콜에 대응하는 커널 코드가 커널 모드에서 실행됩니다.
✔️ 종류
- 프로세스/스레드 관련
- 파일 I/O 관련
- 소켓 관련 ⇒ 네트워크 통신
- 장치(device) 관련
- 프로세스 통신 관련 ⇒ 프로세스끼리의 통신
💋 system interrupt
system interrupt는 프로세스가 ‘이벤트가 일어났다’고 커널에게 알려주는 방법입니다.
system interrupt는 정말 아무 때나 일어납니다.
interrupt 발생 시, CPU는 즉각적으로
interrupt 처리를 위해 커널 코드를 커널 모드에서 실행합니다.
✔️ 종류
- 전원에 문제가 생겼을 때
- I/O 작업이 완료되었을 때
- quantum이 끝났을 때
- 숫자를 0으로 나누거나, 잘못된 메모리 공간에 접근을 시도하는 등 trap이 발생했을 때
💋 system call VS system interrupt
💋 프로그래밍 언어와 system call
하드웨어 또는 시스템 관련 기능은 어떤 프로그램이더라도 직접 할 수 없고, system call을 통해서만 사용 가능합니다. 우리는 직접 system call을 사용한 적이 없지만, 자연스럽게 파일 I/O, 네트워크 I/O, 프로세스나 스레드 관련 작업을 해왔습니다.
우리가 사용하는 high level 프로그래밍 언어들이 시스템 콜을 추상화해서 간접적으로 사용할 수 있도록 제공했기 때문입니다.
Thread thread = new Thread();
thread.start()
스레드를 만드는 것은 system call을 통해서만 가능합니다. 우리는 스레드 객체만 만들었는데, 어떻게 스레드가 생겼을까요?
thread.start()
메서드를 찾아보면 아래와 같습니다.
public synchronized void start() {
if (this.threadStatus != 0) {
throw new IllegalThreadStateException();
} else {
this.group.add(this);
boolean started = false;
try {
this.start0();
started = true;
} finally {
try {
if (!started) {
this.group.threadStartFailed(this);
}
} catch (Throwable var8) {
}
}
}
}
여기서 호출하고 있는 this.start0()
을 보면, native
라는 키워드를 확인할 수 있습니다.
private native void start0();
native
는 운영 체제를 말하는 경우가 대부분이고, Java Native Interface(JNI)를 통해서 OS의 기반이 되는 system call을 호출하게 됩니다. 이 인터페이스는 운영체제별로 구현체가 다르며, 리눅스라면 clone
이라는 system call을 호출합니다.
clone
은 일반적으로 프로세스를 생성할 때 사용되는 시스템 콜이며, 리눅스에서는 스레드도 내부적으로 프로세스로 취급되며, clone
시스템 콜은 새로운 프로세스(또는 스레드)를 생성하는 데 사용됩니다.
high level 프로그래밍 언어는 이런 식으로 system call을 호출하는 코드를 많이 포장해서, 프로그래머가 간접적으로 호출할 수 있도록 합니다.
💋 참고자료
- https://www.baeldung.com/cs/system-call-vs-system-interrupt
- https://www.baeldung.com/linux/system-calls-vs-library-calls
- https://csmylov.blogspot.com/2017/07/user-kernel-interface-system-call.html
- https://medium.com/brundas-tech-notes/linux-clone-system-call-a45f717fa697
- https://www.youtube.com/watch?v=v30ilCpITnY&list=PLcXyemr8ZeoQOtSUjwaer0VMJSMfa-9G-&index=11
도움이 되었다면, 공감/댓글을 달아주면 깃짱에게 큰 힘이 됩니다!🌟
비밀댓글과 메일을 통해 오는 개인적인 질문은 받지 않고 있습니다. 꼭 공개댓글로 남겨주세요!
'Computer Science > Operating System' 카테고리의 다른 글
[OS] MacOS(m1/m2) ARM64 아키텍처에서 Virtualbox 설치하기 (0) | 2024.03.06 |
---|---|
[OS] I/O 처리 방식: Blocking, Non-Blocking, Synchronous, Asynchronous 차이 명확하게 알아보자! (2) | 2023.11.26 |
[OS] CPU Scheduler: 운영체제가 CPU에게 일 시키는 방법(Dispatcher, 비선점 VS 선점 스케줄링, 스케줄링 알고리즘) (0) | 2023.11.24 |
[OS] OS, Java에서 프로세스의 상태 (State of Process in OS and Java) (0) | 2023.11.23 |
[OS] 데드락(Deadlock)은 언제 발생하고, OS, Java에서 어떻게 해결할까? (1) | 2023.11.22 |