[CS] 시스템 콜(System Call)

시스템 콜(System Call)이란?

시스템 콜
프로그램(사용자)이 운영체제(OS)에게 무언가를 요청하는 방법이다.

쉽게 말하면,
"사용자가 직접 못 하는 일"을 운영체제에게 대신해달라고 부탁하는 공식 통로이다.


왜 필요한가?

  • 운영체제는 컴퓨터 자원을 보호해야 한다.
    • 예를 들어 메모리, 파일, 네트워크, 하드디스크 등은 아무 프로그램이나 마음대로 못 건드려야 한다.
  • 그래서 사용자 프로그램은 직접 하드웨어나 시스템 자원에 접근할 수 없다.
  • 대신 운영체제에 '요청'을 보내야 한다 → 이때 쓰는 공식 통로가 바로 시스템 콜이다.

시스템 콜 비유 : 이 이미지는 GPT로 생성되었다.

학교에서 급식을 먹고 싶으면, 학생이 직접 주방에 들어가 음식을 가져오지 않는다.
대신 급식 아줌마(운영체제)에게 요청한다.
시스템 콜은 "밥 주세요" 하는 요청이다.

예시

하고  싶은 일 시스템 콜 이름
파일 열기 open()
파일 읽기 read()
파일 쓰기 write()
새 프로세스 만들기 fork()
프로그램 실행하기 exec()
메모리 공간 확보하기 mmap()
프로세스 종료하기 exit()

 

  • 프로그램은 직접 자원 접근 하면 안된다.
  • 반드시 시스템 콜을 통해 요청하고, 운영체제가 대신 처리해 준다.

실제 예시 코드 (C 언어)

#include <unistd.h>
#include <fcntl.h>

int main() {
    int fd = open("hello.txt", O_RDONLY); // 파일 열기 (open은 시스템 콜이다)
    char buffer[100];
    read(fd, buffer, 100);                // 파일 읽기 (read도 시스템 콜이다)
    close(fd);                             // 파일 닫기 (close도 시스템 콜이다)
    return 0;
}
  • open(), read(), close() 모두 시스템 콜이다.
  • 호출하면 커널(운영체제)로 넘어가서 처리된다.

시스템 콜의 특징 정리

특징 설명
사용자 모드 → 커널 모드 전환 시스템 콜을 부르면 CPU 모드가 바뀜
보호된 자원 접근 가능 파일 시스템, 메모리, 네트워크 등을 안전하게 사용 가능
비용이 크다 사용자-커널 전환이 느릴 수 있어서 시스템 콜은 가급적 줄이는 게 좋다

시스템 콜 흐름 과정

1. 프로그램이 시스템 콜 함수를 호출한다

int fd = open("hello.txt", O_RDONLY);
  • 사용자가 open() 같은 함수를 호출한다.
  • 이 함수는 사실 라이브러리(glibc) 가 제공하는 얇은 껍데기 함수일 뿐이다.
  • 이 껍데기 함수는 내부에서 시스템 콜 넘버를 설정하고 특수 명령어(trap instruction)를 실행한다.

2. CPU가 트랩(Trap)을 발생시킨다

  • Trap현재 실행 흐름을 커널로 강제 전환하는 특수한 명령이다.
  • 예를 들어 x86 아키텍처에서는 int 0x80이나 syscall 명령어를 사용한다.
  • 이 순간 CPU는:
    • 사용자 모드(User Mode) → 커널 모드(Kernel Mode)로 전환한다.
    • 현재 실행 중이던 프로그램 콘텍스트를 저장한다.

3. 커널이 시스템 콜 번호를 읽는다

  • 사용자 프로그램은 "내가 요청한 시스템 콜 번호"를 레지스터에 넣어둔다.
    • 예: open()은 시스템 콜 번호 2번이라고 치자.
  • 커널은 이 번호를 읽고,
  • 시스템 콜 디스패치 테이블(System Call Dispatch Table)에서
    • "번호 2번 → sys_open()" 이렇게 연결된 함수를 찾아낸다.

4. 커널이 요청된 작업을 수행한다

  • 이제 커널은 직접 파일 시스템에 접근해서 "hello.txt"를 찾아 연다.
  • 이 과정에서:
    • 파일 경로 확인
    • 접근 권한 체크
    • 파일 디스크립터 할당
    • 에러 체크
    • 등등을 처리한다.

5. 작업 결과를 프로그램에 반환한다

  • 작업이 끝나면 결과(예: 파일 디스크립터 번호, 에러코드)를 레지스터에 저장한다.
  • CPU는 커널 모드에서 사용자 모드로 돌아온다.
  • 프로그램은 시스템 콜 결과를 받아 다음 작업을 진행한다.