커널 모드 vs 유저 모드 — CPU 특권 레벨과 Ring의 의미
CPU에는 특권 레벨이 있다
컴퓨터 보안의 핵심 아이디어 중 하나는 "모든 코드가 동등하게 신뢰받아서는 안 된다"는 거예요. 사용자가 설치한 앱이 OS 핵심 데이터를 마음대로 바꿀 수 있다면 큰일 나겠죠.
그래서 x86/x64 CPU는 하드웨어 레벨에서 특권 레벨(Privilege Level)을 구현했어요. 이걸 Ring이라고 부릅니다.
CPU는 현재 실행 중인 코드가 어느 Ring에 있는지 추적하고, Ring에 따라 허용되는 명령어와 메모리 접근 범위를 하드웨어 레벨에서 제한합니다.
Ring 0 (커널 모드) — 모든 권한
Ring 0에서 실행되는 코드는 CPU가 할 수 있는 모든 것을 할 수 있어요.
- 물리 메모리 전체에 직접 접근 가능
- in, out 같은 특권 명령어(I/O 포트 직접 접근) 실행 가능
- CPU 레지스터(CR0, CR3 등) 직접 읽기/쓰기 가능
- 인터럽트 제어 가능
- 페이지 테이블 수정 가능
드라이버 코드는 Ring 0에서 실행됩니다. 그래서 드라이버에 버그가 있으면 시스템 전체가 죽어버려요 — BSOD가 바로 그겁니다.
Ring 3 (유저 모드) — 제한된 권한
Ring 3에서 실행되는 코드는 CPU가 강제로 제약을 걸어둡니다.
- 자신의 프로세스 주소 공간에만 접근 가능 (다른 프로세스 메모리 직접 접근 불가)
- 특권 명령어 실행 시도 → 즉시 예외(Exception) 발생
- 하드웨어에 직접 접근 불가 — 커널에 요청해야 함
- 앱이 크래시해도 OS와 다른 프로세스는 영향 없음
이 제약 덕분에 어떤 앱이 오작동해도 OS 자체는 살아있을 수 있어요. Ring 3 코드가 Ring 0 영역에 손을 뻗으면 CPU가 즉시 차단하고 OS에 알립니다.
그렇다면 앱은 어떻게 파일을 읽을까? — 시스템 콜
Ring 3에서 실행되는 앱이 파일을 읽으려면, 직접 디스크에 접근할 수 없으니까 커널(Ring 0)에 "파일 좀 읽어줘"라고 요청해야 해요. 이 요청 메커니즘을 시스템 콜(System Call)이라고 합니다.
예를 들어 우리가 이런 코드를 쓴다고 해볼게요:
// C 코드 (유저 모드) HANDLE hFile = CreateFile( L"C:\\test.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );이 한 줄의 API 호출이 실제로 커널까지 도달하는 과정을 따라가 보면:
3단계의 syscall 명령어가 핵심이에요. x64에서는 syscall, 32bit에서는 int 0x2E 또는 sysenter가 쓰였어요. 이 명령어가 실행되는 순간, CPU는 특권 레벨을 Ring 3에서 Ring 0으로 바꾸고 미리 정해진 커널 진입점으로 점프합니다.
syscall 명령어가 하는 일
CPU 내부적으로 syscall이 실행되면 다음 일이 일어나요:
- 현재 스택 포인터, 명령어 포인터, 플래그를 저장
- CS 세그먼트 셀렉터를 Ring 0 코드 세그먼트로 변경
- LSTAR MSR 레지스터에 저장된 주소(커널 진입점)로 점프
- 커널이 요청을 처리하고 sysret 명령으로 복귀
컨텍스트 스위치(Context Switch) 비용
유저 모드 → 커널 모드 전환은 공짜가 아니에요. 매번 전환할 때마다 CPU 레지스터 저장/복원, TLB 플러시 등의 오버헤드가 발생합니다. 그래서 고성능 I/O 시스템(io_uring, Windows I/O Completion Ports 등)은 커널 진입 횟수를 줄이는 방향으로 설계되어 있어요.
| 구분 | 커널 모드 (Ring 0) | 유저 모드 (Ring 3) |
|---|---|---|
| 실행 주체 | 드라이버, ntoskrnl.exe | 일반 앱, 프레임워크 |
| 메모리 접근 | 전체 물리/가상 메모리 | 자신의 주소 공간만 |
| 하드웨어 접근 | 직접 가능 | 시스템 콜을 통해서만 |
| 크래시 영향 | BSOD — 시스템 전체 종료 | 해당 프로세스만 종료 |
| 보안 권한 | 최고 권한 | 프로세스 토큰 권한 이하 |
실제로 시스템 콜을 들여다보기
WinDbg나 x64dbg로 ntdll!NtCreateFile의 어셈블리를 보면 이런 코드가 나와요:
; ntdll!NtCreateFile (x64) mov r10, rcx ; 첫 번째 인자를 r10에 백업 (syscall 규약) mov eax, 55h ; 시스템 콜 번호 (0x55 = NtCreateFile, 버전마다 다름) syscall ; Ring 3 → Ring 0 전환! ret ; 커널이 결과 반환 후 여기로 복귀딱 네 줄이에요. 이게 전부입니다. 단순하지만 이 네 줄 안에 OS 보안 모델의 핵심이 담겨 있어요.
- x86/x64 CPU는 Ring 0~3의 특권 레벨을 지원하며, Windows는 Ring 0(커널)과 Ring 3(유저)만 사용합니다.
- Ring 0는 모든 권한, Ring 3는 자신의 주소 공간만 접근 가능합니다.
- 유저 앱이 커널 기능을 쓰려면 시스템 콜(syscall)을 통해 요청해야 해요.
- 시스템 콜 시 CPU가 하드웨어 레벨에서 특권 레벨을 전환합니다.
- 드라이버는 Ring 0에서 실행되므로, 버그는 BSOD로 이어집니다.
#커널모드 #유저모드 #Ring0 #시스템콜 #특권레벨
'Programming > 7. Device Driver' 카테고리의 다른 글
| Windows 아키텍처 기초 - 5화 페이징 메커니즘 (0) | 2026.05.22 |
|---|---|
| Windows 아키텍처 기초 - 4화 가상 메모리와 주소 공간 (0) | 2026.05.21 |
| Windows 아키텍처 기초 - 2화 Windows OS 구조 개관 (0) | 2026.05.19 |
| Windows 커널 & 드라이버 완전 정복 목차 (0) | 2026.05.18 |
| Windows 아키텍처 기초 - 1화 시리즈 소개 & 전체 로드맵 (0) | 2026.05.18 |