윈도우 인터널즈

I/O 시스템 02 - 디바이스 드라이버

묭묭.cpp 2024. 10. 18. 14:32

I/O 시스템 02 - 디바이스 드라이버

디바이스 드라이버

디바이스 드라이버의 유형

유저 모드 드라이버

  • 윈도우 서브시스템 프린터 드라이버
    • 장치 독립적인 그래픽 요청을 프린터 특정적인 명령으로 변환
  • 유저 모드 드라이버 프레임워크(UMDF) 드라이버
    • 유저 모드에서 실행되는 하드웨어 디바이스 드라이버
    • UMDF는 ALPC를 통해 커널 모드 UMDF 지원 라이브러리와 통신

커널 모드 디바이스 드라이버

  • 파일 시스템 드라이버
    • 파일 I/O 요청을 받아 좀 더 명시적인 요청을 생성하여 대용량 저장소나 네트워크 디바이스 드라이버로 I/O 요청을 수행
  • 플러그앤플레이 드라이버
    • 하드웨어와 함께 동작하고 원도우 전원 관리자와 PnP 관리자와 통합되어 동작
    • PnP 드라이버에는 대용량 저장 장치와 비디오 어댑터, 입력 장치, 네트워크 어댑터를 위한 드라이버 등이 있음
  • 넌플러그앤플레이 드라이버
    • 커널 익스텐션을 포함하며, 시스템 기능을 확장하는 드라이버나 모듈
    • 실제 하드웨어를 관리하지 않기 때문에 PnP나 전원 관리자와 통합되지 않음

WDM 드라이버

  • 윈도우 드라이버 모델을 준수하는 드라이버
  • 윈도우 전원 관리와 플러그앤플레이, WMI를 지원
  • 대부분의 플러그앤플레이 드라이버는 WDM 모델을 따름

WDM 드라이버의 종류

  • 버스 드라이버
    • 논리적 버스나 물리적 버스를 관리
    • PCMCIA와 PCI, USB, IEEE 1394 등이 있음
    • 장치가 자신이 관리하는 버스에 연결되는 것을 감지
    • 이를 PnP 관리자에게 알려주는 역할과 버스의 전원 설정을 관리할 책임이 있음
  • 펑션 드라이버
    • 특정 유형의 장치를 관리
    • PnP 관리자를 통해 장치를 펑션 드라이버(function driver)에 제공
    • 펑션 드라이버는 장치를 조작하는 인터페이스를 운영체제에게 제공
      • 펑션 드라이버가 장치의 동작에 대해 가장 많이 알고있음
  • 필터 드라이버
    • 펑션 드라이버의 위쪽이나 아래쪽, 혹은 버스 드라이버 상위에 존재하는 논리적 계층
    • 장치나 다른 드라이버의 동작을 확장 혹은 변경시킴

WDM 디바이스 노드(devnode) 구성

  • 물리 디바이스 객체(PDO)와 하위 필터
  • 펑션 디바이스 객체(FDO)를 생성하는 펑션 드라이버
  • 상위 필터로 이루어진 디바이스 노드(devnode)
  • 여기서 반드시 필요한 계층은 PDO와 FDO
    • 다양한 필터는 존재하지 않을 수 있음

6-5

WDM에서는 어떤 드라이버도 특정 장치의 모든 부분을 제어할 책임을 지지 않음

  • 버스 드라이버는 버스에 추가되거나 제거되는 디바이스를 감지하고 PnP 관리자를 도와 버스 장치를 열거
  • 버스 종속적인 구성 설정 레지스터 접근이나 경우에 따라서는 버스 장치의 전원 관리 등을 책임
  • 일반적으로 펑션 드라이버가 장치의 하드웨어에 접근하는 유일한 드라이버
    • 이후 플러그앤플레이 관리자 절에서 이런 장치가 존재하게 되는 정확한 방식을 설명

계층적 드라이버

드라이버는 각 장치가 적절하게 동작하는 데 필요한 기능의 한 부분 제공

  • 하드웨어 지원은 WDM 버스 드라이버와 펑션 드라이버, 필터 드라이버에 추가적인 다음 컴포넌트로 나누어짐

추가적인 컴포넌트들

  • 클래스 드라이버
    • 하드웨어 인터페이스가 표준화되어 있는 특정 클래스 장치(키보드, 디스크 등)의 I/O 처리를 구현
  • 미니클래스 드라이버
    • 특정 부류 장치에 대해 벤더 정의된 I/O 처리를 구현
    • 커널 모드 DLL이고, 직접 IRP 처리를 하지 않음
    • 클래스 드라이버가 미니클래스 드라이버를 호출
  • 포트 드라이버
    • SATA 같은 I/O 포트 유형에 따른 I/O 요청의 처리를 구현
    • 커널 모드 라이브러리 함수로 구현
    • 이는 거의 마이크로소프트만 작성
      • 표준화 되어 있음
  • 미니포트 드라이버
    • 특정 포트에 대한 범용적인 I/O 요청을 특정 네트워크 어댑터 같은 어댑터 유형으로 매핑
    • 포트 드라이버가 제공하는 함수를 임포트하는 실제 디바이스 드라이버
    • 커널 모드 DLL이고, 직접 IRP 처리를 하지 않음

드라이버의 구조

핵심 드라이버 함수 루틴

  • 초기화 루틴
    • I/O 관리자는 운영체제에 드라이버를 로드할 때 WDK에 정의된 GSDDriverEntry에 설정된 초기화 루틴 실행
    • 이는 스택 오버플로우 오류에 대한 컴파일러의 대첵(쿠키)를 초기화
    • 드라이버의 나머지 루틴을 I/O 관리자에 등록하기 위해 시스템 데이터 구조체를 채워 넣고 전역적인 모든 초기화를 수행
  • Add-Device 루틴
    • 플러그앤플레이를 지원하는 드라이버는 add-device 루틴을 구현
    • PnP 관리자는 드라이버가 책임지고 있는 장치가 발견될 때마다 이 루틴을 통해 드라이버에 통지
    • 일반적으로 이 루틴 안에서 장치를 나타내는 디바이스 객체를 생성
  • 디스패치 루틴 집합
    • 디바이스 드라이버가 제공하는 주요 함수들
      • open, close, read, write, 플러그앤플레이 기능
    • I/O 고나리자는 I/O 동작을 수행하기 위해 호출될 때 IRP를 생성하고 드라이버의 디스패치 루틴 중 하나를 통해 드라이버를 호출
  • Start I/O 루틴
    • 드라이버가 데이터 전송이나 수신을 수행하기 위해 이 루틴을 사용
    • 들어오는 I/O 요청을 큐에 넣기 위해 I/O 관리자를 의존하는 드라이버에서만 정의
    • 드라이버가 한 번에 오직 하나의 IRP를 처리할 수 있게 IRP를 직렬화
      • 드라이버는 여러 IRP를 동시에 처리 가능하나
      • 대부분의 장치는 동시에 여러 I/O 요청을 처리할 수 없음
  • 인터럽트 서비스 루틴(ISR)
    • 장치가 인터럽트를 발생시키면 커널의 인터럽트 디스패처는 제어를 ISR로 옮김
      • 이는 DIRQL(디바이스 인터럽트 요청 레벨)에서 동작
      • ISR에서는 낮은 레벨의 인터럽트를 불필요하게 막는 것을 피하기 위해 적은 작업을 수행해야 함
    • ISR은 인터럽트의 남은 부분을 처리하기 위해 DPC를 큐에 넣음
    • 인터럽트 구동 장치를 지원하는 드라이버만 ISR을 가짐
      • ex) 파일 시스템 드라이버는 ISR을 갖지 않음
  • 인터럽트 서비스 DPC 루틴
    • ISR 실행 이후 장치 인터럽트를 처리하는 대부분의 작업을 수행
    • IRQL 2에서 실행
      • DIRQL과 패시브(0) 레벨과의 타협점
    • 일반적인 DPC 루틴은 I/O 완료에 착수하고 장치에 대해 큐에 있는 그 다음 I/O 작업을 시작

6-6

위 그림에는 없지만 수많은 디바이스 드라이버에서 찾아볼 수 있는 루틴

  • 한 개 이상의 I/O 완료 루틴(I/O completion routine)
    • 걔충화된 드라이버에서 하단의 드라이버가 IRP 처리를 완료했을 때 이를 통지하기 위한 루틴
  • I/O 취소 루틴(cancel I/O routine)
    • I/O가 취소될 수 있을 때 가질 수 있는 루틴
    • CancelIo 등이 호출될 때 여기에 취소 루틴이 실행됨
    • 취소된 상태로 IRP를 완료시키고, IRP 처리 중 획득된 모든 리소스를 반환할 책임을 가짐
  • 패스트 디스패치 루틴
    • 파일 시스템 드라이버와 같이 캐시 관리자를 사용하는 드라이버는 커널이 드라이버에 접근할 때 I/O 처리를 우회하기 위해 제공하는 루틴
  • 언로드 루틴
    • 드라이버에서 사용 중인 모든 시스템 리소스를 해제할 수 있게하는 루틴
    • 초기화 루틴에서 획득한 리소스는 일반적으로 여기서 해제
    • 언로드 루틴은 장치에 대한 모든 핸들이 닫힌 후 수행됨
      • 로드와 언로드는 드라이버가 지원하면 언제든지 가능
  • 시스템 종료 통지 루틴
    • 시스템이 종료될 때 정리 작업을 수행하는 루틴
  • 오류 로깅 루틴
    • 오류 로깅을 위한 루틴

드라이버 객체와 디바이스 객체

I/O 관리자가 사용하는 시스템 객체

  • 드라이버 객체
    • 시스템 개별 드라이버를 나타냄(DRIVER_OBJECT 구조체)
    • I/O 관리자는 드라이버 객체로부터 각 드라이버의 디스패치 루틴(진입점)의 주소를 얻음
    • I/O 관리자가 드라이버가 시스템에 로드될 때 생성 -> DirverEntry 초기화 루틴 호출
  • 디바이스 객체
    • 시스템 상의 물리 장치나 논리 장치를 나타냄(DEVICE_OBJECT 구조체)
    • 버퍼에 필요한 버퍼 정렬(alignment)과 들어온 IRP를 보유하는 디바이스 큐의 위치 등을 기술
    • 핸들과 통신하는 객체로 모든 I/O 동작의 대상이됨
    • 드라이버 로딩 완료 후 IoCreateDevice 등의 함수로 디바이스 객체 생성 가능
    • 드라이버 객체는 여러개의 디바이스 객체를 가질 수 있음

드라이버 객체와 디바이스 객체의 관계

6-7

드라이버에 관한 정보를 위해 객체를 이용한다의 의미

  • I/O 관리자가 개별 드라이버에 대한 세부 사항을 알 필요가 없음
  • 단지 드라이버를 찾기 위해 포인터를 따라갈 뿐
  • 이식 가능한 계층을 제공하고 새로운 드라이버를 쉽게 로드할 수 있음

장치 열기

파일 객체

  • 장치에 대한 핸들을 나타내는 커널 모드 자료 구조체
  • 두 개 이상의 유저 모드 프로세스가 공유 가능
  • 이름을 가질 수 있고 객체 기반의 보안으로 보호됨
  • 동기화 또한 지원
  • 윈도우 익스큐티브의 다른 컴포넌트처럼 I/O 시스템 내의 공유 리소스는 객체로 관리됨

호출자가 파일을 열면

  • I/O 관리자는 파일 객체에 대한 핸들을 반환
  • 이런 작업이 일어나긴 전 드라이버는 장치를 오픈해도 되는지 초기화 작업을 드라이버에 허용할지에 대한 요청을 Create 디스패치 루틴(IRP_MJ_CREATE)을 받음

파일은 ACL(Access-Control List)을 가진 보안 디스크립터에 의해 보호됨

  • I/O 관리자는 해당 파일의 ACL이 스레드가 요청한 방식의 접근을 허용하는지 보안 서브시스템에게 질의
  • 허용한다면 허용된 접근 권한과 반환될 파일 핸들을 연결
  • 원래의 요청에 명시되지 않은 추가적인 명령을 수행하길 원한다면
    • 스레드는 또 다른 보안 체크를 수반하는 추가적인 핸들을 얻기 위해 같은 파일을 다시 염
    • 혹은 핸들을 복제함

파일 객체는 익스큐티브 객체와는 다름

  • 리소스 자체가 아닌 공유 가능한 리소스의 메모리 기반 표현
  • 파일 자체는 공유되는 데이터나 텍스트를 담고 있음
  • 스레드가 파일을 열때마다 핸들 특정적 속성을 갖는 새로운 파일 객체가 생성됨
  • 파일이 공유되더라도 전용 바이트 오프셋을 가짐
  • 핸들이 복제가 일어나는 경우나 상속받는 경우를 제외하면 프로세스에 있어 고유함

핸들은 프로세스에 고유하나 물리 리소스는 아님

  • 동기화가 필요함
    • 배타적 쓰기 접근을 지정
    • 혹은 LockFile 함수를 사용하여 파일의 일부분을 잠글 수 있음
반응형