커널(kernel), 일명 슈퍼바이저(supervisor)는 운영체제의 핵심 프로그램으로 일반적으로 시스템 전체에 대한 제어권을 가진다. 메모리에 항상 상주하여 하드웨어와 소프트웨어 간 상호작용을 가능케 하여, 운영체제의 아래 역할을 담당한다.
- 장치 드라이버를 통한 하드웨어 리소스 제어: 메모리, 입출력, 암호화 등
- 프로세스 간 위의 하드웨어 리소스 할당에 대한 갈등 중재
- 공통 리소스 활용의 최적화: CPU 및 캐시 사용률, 파일 시스템, 네트워크 소켓 등
운영체제 설계에 따라 커널은 크게 세 가지의 아키텍처로 설계될 수 있다.
본 부문에서 자주 인용될 "서비스"란, 호출 가능한 커널 루틴 혹은 그 집합을 의미한다.
모놀리식 커널(monolithic kernel)은 모든 서비스가 단일 프로그램으로 빌드되어 커널 공간에서 처리하는 구조이다. 단조로운 구조에 관리가 매우 편하고, 단일 프로그램에서 모든 커널 작업 및 서비스가 수행되니 성능 속도가 매우 빠르다. 단, 커널 공간의 특성상 사소한 오류가 시스템 전체에 영향을 줄 수 있는 위험이 항상 존재한다. 운영체제 런타임 도중에 장치 드라이버를 언제든지 불러올 수 있는 모듈성(modularity)을 지원한다.
마이크로소프트의 MS-DOS 및 윈도우 9x 시리즈가 모놀리식 커널를 사용하였다.
마이크로커널(microkernel)은 운영체제 구동에서 기초적이지만 필연적인 저급 커널 서비스만을 제외한 나머지를 사용자 공간으로 분리시킨 구조이다: 스케줄링, 메모리 관리, 기초적인 IPC가 최소한으로 마련되어야 할 서비스이다. 한편, 사용자 모드에서 고급 커널 서비스를 제공하는 프로그램들을 서버(server)라고 부른다.
마이크로커널의 기초적인 IPC 서비스는 사용자 모드에 위치한 서버 혹은 장치 드라이버 간 통신을 위해 반드시 필요한 기능이다.
모놀리식 커널의 단점인 방대한 커널 이미지로 인한 코드 관리의 어려움 및 장치 드라이버 충돌에 의한 커널 전체에 미치는 악영향을 해소하고자 고안되었다. 커널 서비스의 서버화는 커널 개발 및 업데이트 시간을 단축시키지만, 사용자 모드에 위치하여 하드웨어 접근성 효율이 떨어진다. IPC 통신으로 인한 성능 저하 및 커널 동작 절차의 복잡성도 단점으로 함께 지적되었다.
하이브리드 커널(hybrid kernel)은 마이크로커널처럼 서비스에 따라 서버가 나뉘어져 있으나, 모놀리식 커널처럼 전부 (혹은 대부분) 커널 공간에 존재한다. 결국 시스템 안전성 취약점은 여전히 존재하지만, 마이크로커널에 비해 사용자 및 커널 모드 전환이 불필요하여 커널 서비스의 성능 오버헤드가 없다.
마이크로소프트의 윈도우 NT가 하이브리드 커널의 영향을 받은 대표적인 운영체제이다.
윈도우 NT 운영체제의 커널 이미지 ntoskrnl.exe는 아래와 같이 구성된다.
이미지 | 계층 | 구성 | |||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
ntoskrnl.exe (모듈명: nt ) | Executive | 시스템 서비스 담당자 | |||||||||
입출력 관리자 | 캐시 관리자 | 보안 참조 모니터 | 전원 관리자 | PnP 관리자 | 메모리 관리자 | 프로세스 관리자 | 개체 관리자 | 구성 관리자 | ALPC | ||
Kernel | 스케줄링, 동기화, 인터럽트 등 기초적인 핵심 함수 제공 |
Executive는 특정 작업을 수행하는 여러 구성원들로 이루어진 ntoskrnl.exe의 상위 계층이다. 한편, Kernel 계층은 모듈에서 필요로 하는 기초적인 커널 함수들을 제공하는 하위 계층이며 마이크로커널의 역할을 담당한다. 이러한 구조의 정립으로 Kernel은 단순히 OS 매커니즘을 구현하고, Executive는 이를 활용하여 실질적인 정책 결정에 기여한다.
아래는 nt
모듈의 함수 접두사가 각각 어떤 목적으로 사용되는 지 식별하는 도표이다.
접두사 | 영문 | 의미 |
---|---|---|
Alpc | Asynchronous Local Procedure Call | 비동기 로컬 프로시저 호출 |
Cc | Common cache | 공통 캐시 |
Cm | Configuration manager | 구성 관리자 |
Csr | Client/server runtime | Csrss.exe 서브시스템 프로세스 |
Dbg | Kernel debug support | 커널 디버그 지원 |
Dbgk | Debugging Framework for user mode | 사용자 모드 디버깅 프레임워크 |
Em | Errata manager | 에라타 관리자 |
Etw | Event Tracing for Windows | 윈도우 이벤트 추적 |
Ex | Executive support routines | Executive 지원 루틴 |
FsRtl | File System Runtime Library | 파일 시스템 런타임 라이브러리 |
Hv | Hive Library | 하이브 라이브러리 |
Hvl | Hypervisor Library | 하이퍼바이저 라이브러리 |
Hal | Hardware Abstraction Layer | 하드웨어 추상 계층 |
Io | I/O manager | 입출력 관리자 |
Kd | Kernel Debugger | 커널 디버거 |
Ke | Kernel | 커널 |
Ks | Kernel streaming | 커널 스트리밍 |
Kse | Kernel Shim Engine | 커널 심 엔진 |
Kx | (n/a) | 인터럽트 처리, 세마포어, 스핀락, 멀티스레딩 및 컨텍스트 교환 함수 |
Ky | (n/a) | 트랩 프레임을 생성하고 Kx 접두함수를 호출하는 내부 및 부분 함수 |
Ldr | Loader | PE 포맷 로더 |
Lpc | Local Procedure Call | 로컬 프로시저 호출 |
Lsa | Local Security Authority | 로컬 보안 인증 |
Mm | Memory manager | 메모리 관리자 |
Nt | Native system service (from user mode) | NT 시스템 서비스 (사용자 모드에서 호출) |
Ob | Object manager | 개체 관리자 |
Pf | Prefetcher | 프리페처 |
Po | Power manager | 전원 관리자 |
PoFx | Power framework | 전원 프레임워크 |
Pp | PnP manager | PnP 관리자 |
Ppm | Processor power manager | 프로세서 전원 관리자 |
Ps | Process support | 프로세스 지원 |
Rtl | Run-time library | 런타임 라이브러리; 커널에 직접적으로 가담하지 않지만 네이티브 어플리케이션에서 사용할 수 있는 다양한 유틸리티 함수를 제공한다. |
Se | Security Reference Monitor | 보안 참조 모니터 |
Sm | Store Manager | 스토어 관리자 |
Tm | Transaction Manager | 트랜잭션 관리자 |
Tp | Thread pool manager | 스레드 풀 관리자 |
Ttm | Terminal timeout manager | 터미널 타임아웃 관리자 |
Vf | Driver Verifier | 드라이버 검증 도구 |
Vsl | Virtual Secure Mode library | 가상 보안 모드 라이브러리 |
Wdi | Windows Diagnostic Infrastructure | 윈도우 진단 인프라구조 |
Wfp | Windows FingerPrint | 윈도우 지문 |
Whea | Windows Hardware Error Architecture | 윈도우 하드웨어 오류 아키텍처 |
Wmi | Windows Management Instrumentation | 윈도우 관리 도구 |
Zw | (n/a) | 커널 모드 접근으로 미러된 Nt 시스템 서비스 진입점; 사용자 모드에서 접근할 때 진행하는 파라미터 유효성 검증을 처리하지 않는다. |
† NT 함수 접두사 중에서 p
로 끝나거나 i
로 대체된 건 각각 private 및 internal을 의미하는, 즉 내부 함수를 가리킨다.
커널 개체(kernel object)는 NT 커널 Executive의 다양한 서브시스템이 다루는 리소스 유형들을 프로세스가 접근할 수 있도록 개체 관리자에서 관리하는 정적 구조체의 런타임 인스턴스이다. 대표적으로 (프로세스 관리자의) 프로세스 및 스레드, (입출력 관리자의) 파일, (보안 참조 모니터의) 접근 토큰, (Executive의) 뮤텍스와 세마포어 등이 해당한다. 프로세스는 CreateFile, CreateProcess 등의 윈도우 API로 초기화된 커널 개체을 포인터 대신에 핸들을 통해 접근한다.
커널 개체는 참조되는 한 메모리에 존재하며, 이는 두 가지 유형으로 나누어 집계된다.
핸들 카운트 | 포인터 카운트 |
---|---|
윈도우 API를 통해 프로세스의 핸들 테이블에 배정된 인덱스, 즉 핸들의 개수를 집계한다. | 핸들이나 포인터를 통해 커널 개체를 참조한 개수를 집계한다. 핸들이 열리거나 닫히면 함께 증가 또는 감소한다. |
다시 말해, 한 프로세스에 관여된 커널 개체의 핸들을 모두 닫아도 타 프로세스에 열린 핸들이 있다면 해당 개체는 시스템에 의해 제거되지 않고 존재를 유지한다. 하지만 포인터 참조 카운트 개수에 특이 사항이 발견되면 중지코드 0x18 REFERENCE_BY_POINTER 사유의 BSOD가 발생한다.
다음은 커널 메모리 덤프로부터 notepad.exe 프로세스의 커널 개체 일부에 대한 핸들 및 포인터 카운트를 살펴본 예시이다.
0: kd> !handle 0 f ffff86023505c0c0
PROCESS ffff86023505c0c0
SessionId: 1 Cid: 1c98 Peb: 5f0b2f4000 ParentCid: 1320
DirBase: 290be000 ObjectTable: ffffb101ae3cab00 HandleCount: 245.
Image: notepad.exe
Handle table at ffffb101ae3cab00 with 245 entries in use
0004: Object: ffff86023592ffe0 GrantedAccess: 001f0003 (Protected) (Inherit) Entry: ffffb101af4f8010
Object: ffff86023592ffe0 Type: (ffff86022dace6c0) Event
ObjectHeader: ffff86023592ffb0 (new version)
HandleCount: 1 PointerCount: 32768
0008: Object: ffff8602359300e0 GrantedAccess: 001f0003 (Protected) (Inherit) Entry: ffffb101af4f8020
Object: ffff8602359300e0 Type: (ffff86022dace6c0) Event
ObjectHeader: ffff8602359300b0 (new version)
HandleCount: 1 PointerCount: 32769
입출력 관리자(I/O manager)
입출력 요청 패킷(I/O request packet; IRP)은 WDM 및 윈도우 NT 장치 드라이버가 다른 드라이버 또는 운영체제와 통신하기 위해 사용하는 커널 모드 구조체이다. I/O 요청에 대한 정보들을 구조체 포인터 하나만으로 참조할 수 있으며, 즉시 처리가 불가하면 큐에 대기될 수 있다. I/O 완료는 IoCompleteRequest
루틴에 해당 IRP 구조체의 포인터를 전달하여 입출력 관리자로 보고된다.
일반적으로 IRP는 입출력 관리자가 사용자 모드의 입출력 요청에 대응하여 생성되지만 PnP 관리자, 전원 관리자 등의 다른 시스템 구성요소에 의해 생성되기도 한다. 심지어 드라이버가 생성하여 타 드라이버에게 전달될 수 있다.
PnP 관리자(PnP manager)
하드웨어 추상 계층(Hardware Abstraction Layer; HAL)은 윈도우 NT kernel이 시스템을 구성하는 CPU, 메모리, 디스크 등의 하드웨어와 직접 통신 및 제어하기 위해 필요한 저급 인터페이스를 제공한다. 하드웨어 이식성을 구현하는 핵심 구성요소이며, hal.dll 라이브러리에 정의되어 NT 커널 이미지 ntoskrnl.exe에 로드된다.
윈도우 10, 버전 2004 (코드네임: 20H1) 빌드부터 HAL은 ntoskrnl.exe 안에 포함(혹은 정적 링크)되었으며, DLL은 하위호환을 위해 남겨둔 상태이다.
x86 시스템의 경우, 시스템 부팅 단계에서 APIC 지원 여부에 따라 두 종류의 HAL 중 하나를 시스템에 로드한다: halacpi.dll (ACPI만 지원) 그리고 halmacpi.dll (ACPI + SMP, 즉 APIC 지원). 반면, x64 및 ARM64 시스템은 마더보드에 ACPI와 APIC가 모두 필요하므로 hal.dll 하나만 존재한다.
마이크로소프트에서 제공하는 기본적인 HAL만으로 부족할 경우를 대비하여, 이전에는 3rd 파티 제조사가 자체적으로 HAL을 제공하는 방안을 고려하였지만 현실적이지 않다고 판단하였다. 시스템이 필요에 따라 언제든지 로드가 자유로운 DLL 파일로 제작된 HAL extension을 도입하였으며(예를 들어 HalExtPL080.dll, HalExtIntcLpioDMA.dll 등), 이를 개발하기 위해서는 반드시 마이크로소프트의 협업이 필요하다.
개체 관리자(object manager)