본 글의 일부분은 서적 'Operating Systems: Three Easy Pieces by Remzi H.Arpaci-Dusseau, Andrea C.Arpaci-Dusseau' 내의 이미지와 내용을 포함하고 있습니다 :)
이번 시간에는 System Call에 대해서 좀 더 자세하게 배워보고자 합니다!
System Call은 user mode가 건드릴 수 없는 자원에 대한 operation을
kernel mode에게 대신 해달라고 부탁하는 함수입니다.
System Call의 등장 배경은 아래의 글을 참고해주세요!
programming-workspace.tistory.com/32
System Call을 통해 user mode는 다음과 같은 내용들을 kernel에게 부탁하게 됩니다.
- file system에 접근, file에 쓰고 읽기 등의 작업
- 프로세스를 생성하고 소멸시키기
- 다른 프로세스의 통신하기
- 메모리를 추가로 더 할당하기
등 ...
System Call은 위와 같은 명령어를 user mode에서 kernel mode를 호출함으로써 수행하게 되는데요,
따라서 user mode와 kernel mode간에 오고갈 수 있도록 하는 instruction이 필요합니다.
그것이 바로 Trap instruction과 Return-from-trap instruction입니다.
Trap instruction이란, kernel mode로 진입하는 insturction을 의미합니다.
즉, 권한 레벨을 kernel mode로 높이는 것을 의미합니다.
반대로 Return-from-trap instruction은 다시 user mode로 되돌아 오는 것입니다.
즉, 권한 레벨을 다시 user mode로 되돌리는 것을 의미합니다.
그렇다면, trap은 OS 내에서 어떤 코드를 실행시켜야 하는지 어떻게 알까요?
그 방법은 바로 trap table(interrupt descriptor table, interrupt vector table)과 trap handler를 사용한 System Call Handling 방식에 있습니다.
System call Handling 방식을 이해하기 전에 System-call number에 대한 이해가 필요한데요.
System-call number란, 각 system call마다 부여된 숫자입니다.
즉, 1번이 발생하면 어떤 system call인지 등을 식별할 수 있게 되는 것이죠.
이런 system call number는 user code에 의해서 레지스터에 입력되게 되는데요, 어떠한 방식으로 동작하는 것인지 아래의 그림을 통해서 알아보겠습니다!
아래는 operation이 동작하는 흐름을 간단하게 나타낸 것입니다.
이런 동작을 좀 더 자세히 살펴보면 아래처럼 나타낼 수 있습니다!
우선 User program에 있는 write(), printf() 등을 통해서, glibc와 같은 라이브러리의 해당 system call을 호출하게 됩니다.
그러면 System call stub을 통해서 user mode에서 kernel mode로 진입하게 됩니다!
커널 모드에서 해당 부분을 수행하면서 hardware에 접근하여 output으로 결과를 내게 됩니다.
이러한 과정을 더 낮은 level에서 확인해봅시다!
아래는 fork() system call의 수행 과정을 linux system 에서 확인한 것입니다.
위에서 말했듯이, user program의 코드가 라이브러리를 통해서 libc.a의 fork를 수행하고 있군요.
또한, System call table에 System call의 각 번호들이 어떤 함수를 의미하는지 식별의 역할을 해주고 있습니다.
libc.a에서 눈여겨 볼 부분은
movl 2, %eax
int $0x80 입니다.
movl 2, %eax (%eax라는 레지스터에 2를 넣어라)를 분석해봅시다.
2 는 fork system call의 번호로, 해당 번호를 %eax 레지스터에 넣어주면
후에 kernel에서 %eax 레지스터에 저장된 번호를 가지고 System call table로 찾아가
'아, user mode에서 처리하라고 한 수행이 system call 이 sys_frok()이구나! 를 알아낼 수 있기 때문이죠.
int $0x80 부분은 trap을 거는 부분입니다.
즉, system_call()을 호출하여 kernel mode의 system_call 부분으로 들어갈 수 있도록 하는 것이죠.
이번 시간에는 system call에 대해서, 또 system call의 동작 방식에 대해서 다뤄보았습니다 :)
'운영체제' 카테고리의 다른 글
[운영체제] Thread의 개념 (0) | 2021.01.30 |
---|---|
[운영체제] Direct Execution과 Limited Direct Execution (0) | 2021.01.14 |
[운영체제] 프로세스 API (0) | 2021.01.11 |
[운영체제] 프로세스(Process)란 무엇일까? (0) | 2021.01.10 |
[운영체제] CPU 가상화의 기본 개념 (0) | 2021.01.10 |