사용자 모드와 커널 모드를 알기 전에 우선 큰 그림부터 알아봐요. CPU에는 여러가지 명령어가 존재합니다. 그리고 권한 모드라는 것을 가지고 있죠.
CPU의 구조(Intel 기준)는 아래와 같아요.
지구처럼 층이 존재하고, 외부일 수록 낮은 권한 모드를 가지고 내부일 수록 높은 권한 모드를 가져요. 그리고 가장 내부에 있는 Ring 0을 Kernel
이라고 해요.
사용자 모드User mode
는 Ring 3
에 속하고 일반적인 응용 프로그램이 사용하는 명령이 있어요.
그리고 커널 모드Kernel mode
는 Ring 0
에 속하며 운영체제에서 특권 명령어 실행과 원하는 작업 수행을 위한 자원 접근을 가능케 합니다.
Shell과 Kernel을 직역하면?
Shell : 껍질, 껍데기
Kernel : 알맹이
우리가 C
나 Java
등으로 만든 모든 프로그램은 운영체제 위에서 작동해요. 그리고 프로그램은 커널 모드에서만 실행 가능한 기능들을 사용하는 경우가 있어요. 파일을 여는 함수인 open()
가 대표적인 예죠. 이 기능들, 즉 커널 모드로 기능을 실행하려면 반드시 시스템 콜을 거쳐야 해요. 왜냐하면 응용 프로그램에선 CPU를 실행할 수 없기 때문이에요.
따라서 운영체제는 응용 프로그램이 커널 모드 기능을 실행하기 위해 시스템 콜을 제공해주어야 합니다.
이렇게 나눠 놓음으로써 함부로 응용 프로그램이 전체 컴퓨터 시스템을 해치지 못하게 합니다. 응용 프로그램은 프로그래밍 언어를 아는 사람이라면 누구나 만들 수 있기 때문이에요.
주민등록등본을 예를 들어봐요. 주민등록등본은 위조 방지를 위해 반드시 민원24시나 동사무소에 가서 특별한 신청을 해야만 발급 받을 수 있죠. 여기서 공무원 분들이 바로 특별한 권한을 가지고, 주민등록등본 출력 명령을 수행하는겁니다. 이처럼 사용자 누구나 함부로 특수 명령을 접근하지 못하게 하여 위조 혹은 전체 삭제(!)와 같은 문제를 막기 위해 나누는 겁니다.
// 1. 사용자 모드에서 프로그램 실행
#include <unistd.h>
...
int main(){
int fd;
fd = open("data.txt", O_READ_ONLY);
// 2. open() 시스템 콜 호출
// -> 저장매체에서 가져오고 저장매체는 OS가 관리
// 3. 커널 모드 전환
// 4. open() 함수를 처리하는 sys_open() 커널 함수 호출
// 5. 파일 열기의 low-level 연산 수행(CPU)
// 6. 응용에게 데이터 전달 후 사용자 모드 전환
// 7. open() 함수 이후의 프로그램 실행
if(fd == -1){
printf("Error : Cannot open file\n");
return 1;
} else{
printf("File opened no close\n");
close(fd);
}
return 0;
}
위에 주석으로 설명이 다 되있는거 같긴한데, 복기 겸 끄적여봅니다..ㅎㅎ
프로그램이 실행되면서 시스템 콜을 호출하는 open()
이 호출됩니다. 이때 커널 모드로 전환해서 open()
함수를 처리하는 sys_open()
커널 함수를 호출하게 됩니다. 그 다음 파일 열기의 low-level
연산을 수행하게 되요. 연산이 완료되면 응용 프로그램에게 데이터를 전달한 후 사용자 모드로 전환합니다. 그 다음에 open()
이후의 프로그램을 전개하게 되요.
사용자 모드와 커널 모드는 여기까지 다루겠습니다.