System Call(시스템 콜) 은 사용자 프로그램이 커널 기능을 요청할 때 사용하는 인터페이스다.
운영체제는 사용자 프로그램이 하드웨어나 커널 자원에 직접 접근하는 것을 금지하고, 반드시 시스템 콜을 통해 간접적으로 요청하게 한다.
예: 파일 열기, 읽기, 쓰기, 메모리 할당, 프로세스 생성 등
사용자 프로그램이 시스템 자원에 직접 접근하면 보안·안정성 문제가 발생할 수 있다.
그래서 운영체제는 사용자 모드(User Mode)와 커널 모드(Kernel Mode)를 구분하고, 커널 기능은 시스템 콜을 통해서만 사용할 수 있도록 제한한다.
시스템 콜은 사용자 모드에서 커널 모드로의 모드 전환(Mode Switching) 을 수반한다.
open(), read() 등)// 예시: 파일 열기
int fd = open("file.txt", O_RDONLY);
| 범주 | 시스템 콜 예시 |
|---|---|
| 프로세스 관리 | fork(), exec(), wait(), exit() |
| 파일 시스템 | open(), read(), write(), close() |
| 디바이스 제어 | ioctl(), read(), write() |
| 정보 요청 | getpid(), getuid() |
| 메모리 관리 | mmap(), brk() |
| 통신(IPC) | pipe(), shmget(), msgsnd(), recv() |
| 구조 | 시스템 콜 진입 방법 |
|---|---|
| x86 (32bit) | int 0x80 인터럽트 사용 |
| x86-64 (64bit) | syscall 명령어 사용 (더 빠름) |
최근 리눅스 커널은
syscall명령어를 선호하며, 시스템 콜 번호와 인자 위치가 레지스터로 고정되어 있다.
예:rax= 시스템 콜 번호,rdi,rsi,rdx, … = 인자
Linux 커널 예시:
read(fd, buf, size) 호출0)와 인자 레지스터 설정syscall → 커널 진입sys_read() 함수 호출 → 내부 로직 수행리눅스에서 strace 명령어를 사용하면 프로그램이 호출하는 시스템 콜을 실시간 추적할 수 있다.
strace ./my_program
open("input.txt", O_RDONLY) = 3
read(3, "data", 1024) = 1024
write(1, "data", 1024) = 1024
close(3) = 0
| 항목 | 함수 호출 | 시스템 콜 |
|---|---|---|
| 실행 영역 | 사용자 공간 | 커널 공간 |
| 속도 | 빠름 | 상대적으로 느림 (모드 전환 필요) |
| 예시 | printf() | write() |
| 목적 | 코드 재사용 | 커널 자원 접근 |
표준 라이브러리 함수는 내부적으로 시스템 콜을 사용할 수도 있고, 아닐 수도 있다.
리눅스에서는 시스템 콜 번호가 unistd.h 헤더에 정의되어 있다.
또는 man 2 syscall 또는 /usr/include/asm/unistd_64.h 파일에서 직접 확인 가능
#define __NR_read 0
#define __NR_write 1
#define __NR_open 2
...