본문 바로가기
컴퓨터 공학/운영체제

시스템 콜(System call)

by Montmartree 2020. 4. 22.

 

지난번에 인터럽트에 관하여 설명하였다.

 

인터럽트는 크게 하드웨어와 소프트웨어로 나눠지는데

 

이번에 설명할 시스템 콜(System call)은 소프트웨어 인터럽트의 한 종류이다.

 

 

 

우선, OS는 Dual Mode로 작동된다.

 

Dual이란 2가지를 의미하는데 User Mode와 Kernel Mode이다.

 

일반 응용프로그램은 User Mode에서 실행되고, 응용프로그램이 시스템 자원 및 별도의 명령을 필요로 한다면

 

인터럽트를 발생시켜서 Kernel Mode 내부에서 실행하게끔 설계되어 있다.

 

 

좀 더 쉽게 말하자면, User Mode의 기능과 Kernel Mode의 기능이 나뉘어져 있고

 

Kernel Mode의 기능은 크리티컬한 기능이 많기때문에 User Mode에서 함부로 접근을 하지 못하게 막는 것이다.

 

 

이렇게 설계한 이유는 당연히도 일반 프로그램의 불필요한 시스템 접근을 막기 위해서이다.

 

 

그렇다면, 시스템 콜이 작동하는 방식을 살펴보자.

 

개발자가 프로그램을 개발할 때, Kernel Mode의 특정 기능을 사용해야 하는 상황이 온다면(C언어의 printf()같은 구문)

 

System call API 함수를 호출해야한다. 이 함수는 컴파일러의 라이브러리에 존재한다.

 

즉, printf 함수 내부의 코드 중엔 시스템 콜 API 함수가 있을 것이다.

 

 

printf(...) {

 

    ...

    write()            <<==   이런 식으로 API 함수가 존재

    ...

}

 

write() {

 

    ...

    movl 4, %eax       <<==    각 시스템 콜의 기능은 system_call_table 이라는 테이블 안에 인덱싱 되어있다.

    int 0x80                  <<==    0x80 인터럽트를 발생시킨다.

    ...

 

}

 

 

리눅스로 예를 들어보자.

 

아래는 리눅스에서의 시스템 콜 작동 방식이다.

 

1. 해당 시스템 콜 기능의 인덱스 번호를 레지스터에 저장한다.

 

2. 0x80 인터럽트를 발생시킨다.

 

3. IDT(Interrupt Descriptor Table)에서 0x80에 해당하는 내용을 찾는다. (0x80은 system_call() 이다.)

 

4. 3번에서 찾은 system_call() 함수의 내부로 들어간다. (여기서 Kernel Mode로 진입)

 

5. 1번에서 저장했던 인덱스 번호를 system_call() 함수 내에 전달한다.

 

6. sys_call_table에서 해당 인덱스에 맞는 기능을 호출한다.

 

7. 수행이 끝나면 다시 User Mode로 돌아온다.

 

 

 

또한, 시스템 콜은 매개변수(parameter)도 전달할 수 있다.

 

이 경우는 3가지의 방식이 있다.

 

 

    1. 매개변수의 값을 레지스터에 직접 저장해서 넘겨주는 방식

 

 

만약, 매개변수의 개수가 CPU의 레지스터 개수보다 많을 경우

 

    2. 매개변수를 메모리에 저장하고, 메모리의 주소를 레지스터에 전달하는 방식

 

    3. 프로그램에 의해 스택으로 전달하는 방식

 

 

 

여기까지가 시스템 콜의 개요이다.

 

다음에는 OS의 5가지 Structure 및 프로세스에 대해서 간략하게 설명할 예정이다.