본문 바로가기
Programming/7. Device Driver

Windows 아키텍처 기초 - 7화 Windows I/O 시스템 개관

by S.W 2026. 5. 25.
Windows 커널 & 드라이버 시리즈 — 7화

Windows I/O 시스템 개관 — 드라이버의 무대를 이해하다

📅 2026 ⏱ 읽기 약 11분 🏷 I/O Manager / 디바이스 스택
앱이 파일을 읽거나 USB 장치에 데이터를 보낼 때, 그 요청이 드라이버에 도달하기까지 어떤 경로를 거칠까요? 이번 화에서는 Windows I/O 시스템의 전체 흐름을 살펴봅니다. 이걸 이해하면 다음 달에 배울 IRP, 디바이스 스택 같은 개념들이 훨씬 자연스럽게 이해될 거예요.

I/O 요청의 여정

앱에서 ReadFile()을 호출하면 그 요청이 실제 하드웨어에 닿기까지 여러 계층을 통과합니다:

📱 앱 (유저 모드) — ReadFile() 호출
↓ syscall
📋 I/O Manager — IRP 생성, 디바이스 스택으로 전달
↓ IRP 전달
🔧 필터 드라이버들 — IRP 가로채기 / 수정 가능
🔧 파일시스템 드라이버 (예: NTFS.sys) — 파일 시스템 로직
🔧 디스크 드라이버 (예: disk.sys) — 섹터 단위 I/O
🔧 버스 드라이버 (예: SATA/NVMe) — 물리 컨트롤러 제어
⚙️ 하드웨어 — 실제 디스크 I/O

각 단계의 드라이버들이 수직으로 쌓인 구조를 디바이스 스택(Device Stack)이라고 해요. I/O 요청은 이 스택을 따라 내려가고, 완료 후에는 반대 방향으로 올라옵니다.

I/O Manager — 중재자

I/O Manager는 이 시스템 전체의 중재자예요. 주요 역할은:

  • IRP 생성 — 앱의 I/O 요청을 IRP(I/O Request Packet)라는 커널 구조체로 변환
  • 라우팅 — 어떤 드라이버가 이 요청을 처리해야 하는지 찾아서 전달
  • 완료 처리 — 드라이버가 IRP를 완료하면, 앱에게 결과를 돌려줌
  • 취소 처리 — 앱이 I/O를 취소하면 드라이버에 취소 요청 전달

드라이버 개발자 입장에서 I/O Manager는 "항상 IRP를 들고 우리 드라이버 문을 두드리는 존재"예요. 우리는 그 IRP를 받아서 처리하고 돌려주면 됩니다.

디바이스 오브젝트 (DEVICE_OBJECT)

드라이버는 하나 이상의 디바이스 오브젝트(DEVICE_OBJECT)를 만들어요. 이 오브젝트가 I/O Manager에게 "이런 이름의 디바이스가 있고, I/O 요청을 받을 준비가 되어 있다"고 알려주는 역할을 합니다.

예를 들어, 디스크 드라이버는 \Device\HarddiskVolume1 같은 이름의 디바이스 오브젝트를 만들어요. 앱이 이 이름을 통해 파일을 열면, I/O Manager가 해당 디바이스 오브젝트를 찾아서 IRP를 보내줍니다.

📌 디바이스 이름 공간 Windows에는 오브젝트 네임스페이스가 있어요. \Device\는 커널 이름 공간이고, \DosDevices\C: 같은 심볼릭 링크가 유저 모드에서 보이는 드라이브 문자와 연결됩니다. WinObj(Sysinternals)로 이 네임스페이스를 탐색해 볼 수 있어요.

IRP — I/O Request Packet

IRP는 I/O 시스템의 핵심 데이터 구조예요. 앱의 I/O 요청 하나당 IRP가 하나 만들어지고, 이 IRP가 디바이스 스택을 따라 여행하면서 처리됩니다.

IRP에는 다음 정보가 담겨있어요:

  • 어떤 종류의 I/O인지 (읽기/쓰기/제어 등)
  • 데이터 버퍼 위치와 크기
  • 완료 후 호출할 콜백 함수 (CompletionRoutine)
  • 각 드라이버 단계마다의 파라미터 (IO_STACK_LOCATION)

IRP의 자세한 구조는 12화에서 깊게 파고들 거예요. 지금은 "I/O 요청을 담는 봉투"라고 생각하면 충분합니다.

동기 I/O vs 비동기 I/O

앱에서 I/O를 요청할 때 두 가지 방식이 있어요:

구분 동기 I/O 비동기 I/O (Overlapped)
앱 동작 I/O 완료까지 기다림 요청 후 다른 작업 계속
완료 통지 함수 리턴으로 알 수 있음 이벤트, IOCP, APC 등으로 알림
적합한 경우 간단한 I/O, 빠른 응답 고성능 서버, 대량 I/O
드라이버 입장 IRP 완료 시 스레드가 깨어남 완료 루틴이 나중에 호출됨

드라이버는 두 방식 모두 동일한 IRP 처리 코드로 대응해요. 동기/비동기 차이는 앱 레벨의 이야기이고, 드라이버는 "IRP 처리 → 완료"라는 흐름은 같습니다.

I/O 완료 포트 (IOCP) — 간단히 맛보기

고성능 서버 개발자에게 친숙한 IOCP(I/O Completion Port)도 이 I/O 시스템 위에 올라타는 매커니즘이에요. 드라이버가 비동기 IRP를 완료하면, 커널이 미리 등록해 둔 I/O 완료 포트에 완료 패킷을 큐잉합니다. 스레드 풀이 이 패킷을 꺼내 처리하죠.

💡 드라이버와 IOCP의 관계 드라이버 개발자가 IOCP를 직접 구현할 필요는 없어요. I/O Manager가 IOCP와의 연동을 자동으로 처리해줍니다. 드라이버는 그냥 IRP를 올바르게 완료(IoCompleteRequest)하면 되고, 나머지는 커널이 알아서 앱에 알려줍니다.

✅ 7화 요약
  • I/O 요청은 앱 → I/O Manager → 디바이스 스택(드라이버들) → 하드웨어 순서로 흐릅니다.
  • I/O Manager가 IRP를 만들고 적절한 드라이버로 라우팅합니다.
  • 드라이버는 디바이스 오브젝트를 만들어 I/O Manager에게 존재를 알려요.
  • IRP는 I/O 요청을 담는 핵심 구조체로, 디바이스 스택을 따라 이동합니다.
다음 화
8화 — 개발 환경 구축: WDK 설치부터 첫 빌드까지 →

#IOManager #IRP #디바이스스택 #WindowsIO #IOCP