커널 아키텍처와 시스템 콜
Linux는 왜 이렇게 설계됐는가
1991년 8월 25일, 핀란드 학생 Linus Torvalds가 comp.os.minix 뉴스그룹에 짧은 게시글을 올렸다. "나는 386(486) AT 클론용으로 자유로운(무료) 운영체제를 만들고 있다." 그 소스는 monolithic kernel — 커널의 모든 핵심 기능이 단일 주소 공간에서 실행되는 구조 — 으로 설계되었고, 30년이 지난 지금도 그 철학이 유지된다.
당시 Andrew Tanenbaum이 "Linux는 구조적으로 1970년대 설계다"라고 비판했지만, Torvalds는 실용주의로 응수했다: 모놀리식 커널은 마이크로커널보다 IPC(프로세스 간 통신) 오버헤드 없이 훨씬 빠르다. 오늘날 Kubernetes·Docker·systemd가 모두 Linux 위에서 돌아가는 것은 이 성능 선택의 결과다.
특권 레벨: Ring 0와 Ring 3
x86 아키텍처는 4개의 보호 레벨(Ring 0 ~ Ring 3)을 정의하지만, Linux는 두 레벨만 쓴다.
- Ring 0 (Kernel Mode): 모든 CPU 명령어 실행 가능, 하드웨어에 직접 접근, 모든 메모리 주소 읽기/쓰기 가능.
- Ring 3 (User Mode): 제한된 명령어만 허용, I/O 포트 직접 접근 불가, 커널 메모리 직접 접근 불가.
프로그램이 파일을 열거나 네트워크 패킷을 보내려면 반드시 커널에 요청해야 한다. 그 창구가 시스템 콜(System Call) 이다.
커널 주요 서브시스템
Linux 커널은 여러 서브시스템으로 나뉜다. 각 서브시스템은 독립적으로 개발되지만 같은 주소 공간에서 실행된다.
| 서브시스템 | 역할 | 핵심 코드 위치 |
|---|---|---|
| 프로세스 스케줄러 | CPU 할당, 선점, 우선순위 | kernel/sched/ |
| 메모리 관리 | 가상 메모리, 페이징, slab 할당자 | mm/ |
| VFS (Virtual File System) | 통일된 파일 추상화 | fs/ |
| 네트워크 스택 | TCP/IP, 소켓 | net/ |
| 디바이스 드라이버 | 하드웨어 추상화 | drivers/ |
| IPC | 파이프, 소켓, 공유 메모리 | ipc/ |
| 보안 (LSM) | SELinux, AppArmor | security/ |
로드 가능 커널 모듈(LKM) 은 모놀리식 설계의 실용적 타협점이다. 드라이버나 파일시스템을 런타임에 insmod/modprobe로 로드하고 rmmod로 제거할 수 있다. 커널 전체를 재빌드할 필요 없다.
시스템 콜: 유저-커널 경계의 관문
시스템 콜은 사용자 프로그램이 커널 기능을 요청하는 유일하고 공식적인 인터페이스다.
x86-64 시스템 콜 호출 규약
x86-64에서 시스템 콜은 syscall 명령어로 트리거된다:
rax레지스터에 시스템 콜 번호를 설정- 인자를 순서대로
rdi,rsi,rdx,r10,r8,r9에 설정 (최대 6개) syscall명령어 실행 → CPU가 Ring 3 → Ring 0으로 전환, 실행 흐름을 커널 진입점으로 이동- 커널이 처리 후 반환 값을
rax에 저장 sysret명령어로 Ring 3 복귀
(Ring 3) glibc wrapper
read(fd, buf, n)
(Ring 0) 레지스터 저장
스택 전환
조회 sys_read() 호출
실행 데이터 복사
rax에 결과
핵심 시스템 콜 카탈로그
# 파일 I/O
open(path, flags, mode) → fd # syscall 2
read(fd, buf, count) → bytes # syscall 0
write(fd, buf, count) → bytes # syscall 1
close(fd) # syscall 3
# 프로세스
fork() → pid # syscall 57 (clone 기반)
execve(path, argv, envp) # syscall 59
exit(status) # syscall 60
wait4(pid, wstatus, opts, rusage) # syscall 61
# 메모리
mmap(addr, len, prot, flags, fd, off) → addr # syscall 9
brk(addr) # syscall 12
munmap(addr, len) # syscall 11
# 네트워크
socket(domain, type, protocol) → fd # syscall 41
bind(fd, addr, addrlen) # syscall 49
connect(fd, addr, addrlen) # syscall 42glibc가 시스템 콜을 감추는 방법
C 표준 라이브러리 glibc는 시스템 콜을 직접 호출하는 대신 래퍼(wrapper) 함수를 제공한다.
// 개발자가 쓰는 코드
ssize_t n = read(fd, buf, sizeof(buf));
// glibc 내부 (단순화)
// 실제로는 아키텍처별 어셈블리로 구현됨
long syscall(SYS_read, fd, buf, count);
// → mov rax, 0; mov rdi, fd; syscall; retstrace 명령어로 프로세스가 실제로 호출하는 시스템 콜을 추적할 수 있다.
$ strace -c ls /tmp
% time seconds usecs/call calls syscall
------ ----------- ----------- --------- --------
38.45 0.000250 10 24 mmap
22.15 0.000144 48 3 read
15.23 0.000099 16 6 openat
9.88 0.000064 32 2 getdents64
...vDSO: 커널 진입 없는 빠른 시스템 콜
일부 시스템 콜은 실제 커널 모드 전환 없이도 응답할 수 있다. 대표적인 예가 gettimeofday() — 현재 시각을 반환하는 호출.
vDSO(virtual Dynamic Shared Object) 는 커널이 모든 프로세스의 가상 주소 공간에 자동으로 매핑하는 소형 공유 라이브러리다. 커널은 타이머 인터럽트마다 vvar 페이지(읽기 전용 공유 메모리)를 업데이트하고, vDSO 코드는 이 페이지를 평범한 메모리 읽기로 접근한다. Ring 전환이 없으므로 전통적인 syscall 대비 약 10배 빠르다.
$ ldd /bin/ls
linux-vdso.so.1 (0x00007ffd3c5f6000) ← 커널이 자동 주입
libselinux.so.1 => ...
libc.so.6 => ...vDSO를 통해 가속되는 주요 함수: clock_gettime(), gettimeofday(), getpid().
Loadable Kernel Modules
드라이버를 커널에 영구 컴파일하지 않고 런타임에 로드하는 방식이다. /lib/modules/$(uname -r)/ 아래에 .ko 파일로 저장된다.
$ lsmod | head -5
Module Size Used by
nf_tables 225280 0
nfnetlink 20480 1 nf_tables
xfs 1572864 2
$ modprobe xfs # 로드
$ rmmod xfs # 제거
$ modinfo xfs | head # 모듈 정보모듈은 Ring 0에서 실행되므로 버그 있는 모듈은 커널 패닉을 일으킬 수 있다. 이 때문에 드라이버 코드에는 서명 검증(module signing)이 적용된다.
정리: 시스템 콜이 중요한 이유
컨테이너·eBPF·성능 분석·보안 정책을 다루는 인프라 엔지니어에게 시스템 콜은 핵심 도구다.
- seccomp: 허용된 시스템 콜 목록만 통과시키는 샌드박스 (Docker 기본값으로 300여 개 중 ~50개를 차단)
- eBPF: 커널 이벤트(시스템 콜 포함)에 후크를 걸어 추적·필터링
- ptrace: 디버거(gdb)와 strace의 기반 — 시스템 콜을 가로채거나 프로세스 레지스터를 검사
다음 편에서는 이 시스템 콜 위에서 동작하는 프로세스와 스레드의 내부 구조를 살펴본다.
References
- vsyscall and vDSO — Linux Inside (0xax)
- vDSO and Virtual System Calls — kernel-internals.org
- System Calls — The Linux Kernel documentation (linux-kernel-labs)
- vDSO — Wikipedia
- Linux Kernel Architecture — Conceptual Architecture (huihoo)
- Linux Kernel Highlights For 2025 — Phoronix
- Understanding and Utilizing Linux VDSO — linuxvox.com
- Linux man page: syscall(2)