디바이스 노드 및 디바이스 스택

Windows에서 디바이스는 플러그 앤 플레이(PnP) 디바이스 트리의 디바이스 노드로 표시됩니다. 일반적으로 I/O 요청이 디바이스로 전송되면 여러 드라이버가 요청을 처리하는 데 도움이 될 수 있습니다. 이러한 각 드라이버는 디바이스 개체와 연결되며 디바이스 개체는 스택에 정렬됩니다. 연결된 드라이버와 함께 디바이스 개체의 시퀀스를 디바이스 스택이라고 합니다. 각 디바이스 노드에는 자체 디바이스 스택이 있습니다.

디바이스 노드 및 플러그 앤 플레이 디바이스 트리

Windows는 플러그 앤 플레이 디바이스 트리 또는 단순히 디바이스 트리라는 트리 구조로 디바이스를 구성합니다. 일반적으로 디바이스 트리의 노드는 복합 디바이스의 디바이스 또는 개별 함수를 나타냅니다. 그러나 일부 노드는 물리적 디바이스와 연결되지 않은 소프트웨어 구성 요소를 나타냅니다.

디바이스 트리의 노드를 디바이스 노드라고 합니다. 디바이스 트리의 루트 노드를 루트 디바이스 노드라고 합니다. 규칙에 따라 루트 디바이스 노드는 다음 다이어그램과 같이 디바이스 트리의 맨 아래에 그려집니다.

디바이스 노드를 보여 주는 디바이스 트리의 다이어그램

디바이스 트리는 PnP 환경에 내재된 부모/자식 관계를 보여 줍니다. 디바이스 트리의 여러 노드는 자식 디바이스가 연결된 버스를 나타냅니다. 예를 들어 PCI Bus 노드는 마더보드의 실제 PCI 버스를 나타냅니다. 시작하는 동안 PnP 관리자는 PCI 버스 드라이버에 PCI 버스에 연결된 디바이스를 열거하도록 요청합니다. 이러한 디바이스는 PCI Bus 노드의 자식 노드로 표시됩니다. 위의 다이어그램에서 PCI Bus 노드에는 USB 호스트 컨트롤러, 오디오 컨트롤러 및 PCI Express 포트를 포함하여 PCI 버스에 연결된 여러 디바이스에 대한 자식 노드가 있습니다.

PCI 버스에 연결된 디바이스 중 일부는 버스 자체입니다. PnP 관리자는 이러한 각 버스에 연결된 디바이스를 열거하도록 요청합니다. 위의 다이어그램에서는 오디오 컨트롤러가 연결된 오디오 디바이스가 있는 버스임을 알 수 있습니다. PCI Express 포트는 디스플레이 어댑터가 연결된 버스이고 디스플레이 어댑터는 하나의 모니터가 연결된 버스임을 알 수 있습니다.

노드를 디바이스 또는 버스를 나타내는 것으로 생각하는지 여부는 사용자의 관점에 따라 달라집니다. 예를 들어 디스플레이 어댑터는 화면에 표시되는 프레임을 준비하는 데 중요한 역할을 하는 디바이스라고 생각할 수 있습니다. 그러나 디스플레이 어댑터는 연결된 모니터를 감지하고 열거할 수 있는 버스라고 생각할 수도 있습니다.

디바이스 개체 및 디바이스 스택

디바이스 개체는 DEVICE_OBJECT 구조의 instance. PnP 디바이스 트리의 각 디바이스 노드에는 정렬된 디바이스 개체 목록이 있으며 이러한 각 디바이스 개체는 드라이버와 연결됩니다. 연결된 드라이버와 함께 정렬된 디바이스 개체 목록을 디바이스 노드의 디바이스 스택 이라고 합니다.

여러 가지 방법으로 디바이스 스택을 생각할 수 있습니다. 가장 공식적인 의미에서 디바이스 스택은 (디바이스 개체, 드라이버) 쌍의 순서가 지정된 목록입니다. 그러나 특정 컨텍스트에서는 디바이스 스택을 디바이스 개체의 순서가 지정된 목록으로 간주하는 것이 유용할 수 있습니다. 다른 컨텍스트에서는 디바이스 스택을 정렬된 드라이버 목록으로 생각하는 것이 유용할 수 있습니다.

규칙에 따라 디바이스 스택에는 위쪽과 아래쪽이 있습니다. 디바이스 스택에서 만들 첫 번째 디바이스 개체는 맨 아래에 있으며 디바이스 스택에 만들고 연결할 마지막 디바이스 개체가 맨 위에 있습니다.

다음 다이어그램에서 Proseware Gizmo 디바이스 노드에는 세 개의(디바이스 개체, 드라이버) 쌍이 포함된 디바이스 스택이 있습니다. 상위 디바이스 개체는 드라이버 AfterThought.sys 연결되고, 중간 디바이스 개체는 드라이버 Proseware.sys 연결되고, 아래쪽 디바이스 개체는 드라이버 Pci.sys 연결됩니다. 다이어그램 중앙에 있는 PCI Bus 노드에는 두 개의(디바이스 개체, 드라이버) 쌍, 즉 Pci.sys 연결된 디바이스 개체와 Acpi.sys 연결된 디바이스 개체가 포함된 디바이스 스택이 있습니다.

proseware gizmo 및 pci 디바이스 노드의 디바이스 스택에서 정렬된 디바이스 개체를 보여 주는 다이어그램

디바이스 스택은 어떻게 생성됩니까?

시작하는 동안 PnP 관리자는 각 버스에 대해 드라이버에게 버스에 연결된 자식 디바이스를 열거하도록 요청합니다. 예를 들어 PnP 관리자는 PCI 버스 드라이버(Pci.sys)에 PCI 버스에 연결된 디바이스를 열거하도록 요청합니다. 이 요청에 대한 응답으로 Pci.sys PCI 버스에 연결된 각 디바이스에 대한 디바이스 개체를 만듭니다. 이러한 각 디바이스 개체를 PDO( 물리적 디바이스 개체 )라고 합니다. Pci.sys PDO 집합을 만든 직후 디바이스 트리는 다음 다이어그램에 표시된 것과 같습니다.

자식 디바이스에 대한 pci 노드 및 물리적 디바이스 개체의 다이어그램

PnP 관리자는 새로 만든 각 PDO와 디바이스 노드를 연결하고 레지스트리를 확인하여 노드에 대한 디바이스 스택의 일부가 되어야 하는 드라이버를 확인합니다. 디바이스 스택에는 하나의 함수 드라이버 만 있어야 하며 필요에 따라 하나 이상의 필터 드라이버가 있을 수 있습니다. 함수 드라이버는 디바이스 스택의 기본 드라이버이며 읽기, 쓰기 및 디바이스 제어 요청을 처리합니다. 필터 드라이버는 읽기, 쓰기 및 디바이스 제어 요청을 처리하는 데 보조 역할을 합니다. 각 함수 및 필터 드라이버가 로드되면 디바이스 개체를 만들고 디바이스 스택에 자체 연결합니다. 함수 드라이버에서 만든 디바이스 개체를 FDO( 기능 디바이스 개체 )라고 하며 필터 드라이버에서 만든 디바이스 개체를 필터 디바이스 개체 (Filter DO)라고 합니다. 이제 디바이스 트리가 이 다이어그램과 같이 표시됩니다.

proseware gizmo 디바이스 노드의 필터, 함수 및 물리적 디바이스 개체를 보여 주는 디바이스 트리의 다이어그램

다이어그램에서는 한 노드에서 필터 드라이버가 함수 드라이버 위에 있고 다른 노드에서는 필터 드라이버가 함수 드라이버 아래에 있음을 확인합니다. 디바이스 스택의 함수 드라이버 위에 있는 필터 드라이버를 상위 필터 드라이버라고 합니다. 함수 드라이버 아래에 있는 필터 드라이버를 하위 필터 드라이버라고 합니다.

PDO는 항상 디바이스 스택의 아래쪽 디바이스 개체입니다. 이는 디바이스 스택이 생성되는 방식에서 비롯됩니다. PDO가 먼저 만들어지고 추가 디바이스 개체가 스택에 연결되면 기존 스택의 맨 위에 연결됩니다.

참고 디바이스용 드라이버가 설치되면 설치 관리자는 INF(정보) 파일의 정보를 사용하여 함수 드라이버인 드라이버와 필터인 드라이버를 결정합니다. 일반적으로 INF 파일은 Microsoft 또는 하드웨어 공급업체에서 제공합니다. 디바이스에 대한 드라이버가 설치되면 PnP 관리자는 레지스트리를 확인하여 디바이스에 대한 함수 및 필터 드라이버를 확인할 수 있습니다.

버스 드라이버

앞의 다이어그램에서 드라이버 Pci.sys 두 역할을 수행하는 것을 볼 수 있습니다. 먼저 Pci.sys PCI Bus 디바이스 노드의 FDO와 연결됩니다. 실제로 PCI Bus 디바이스 노드에서 FDO를 만들었습니다. 따라서 Pci.sys PCI 버스의 함수 드라이버입니다. 둘째, Pci.sys PCI Bus 노드의 각 자식에서 PDO와 연결됩니다. 자식 디바이스에 대한 PDO를 만들었습니다. 디바이스 노드에 대한 PDO를 만드는 드라이버를 노드의 버스 드라이버 라고 합니다.

참조 지점이 PCI 버스인 경우 Pci.sys 함수 드라이버입니다. 그러나 참조 지점이 Proseware Gizmo 디바이스인 경우 Pci.sys 버스 드라이버입니다. 이 이중 역할은 PnP 디바이스 트리에서 일반적입니다. 버스의 함수 드라이버 역할을 하는 드라이버는 버스의 자식 디바이스에 대한 버스 드라이버 역할을 합니다.

사용자 모드 디바이스 스택

지금까지 커널 모드 디바이스 스택에 대해 논의해 왔습니다. 즉, 스택의 드라이버는 커널 모드로 실행되고 디바이스 개체는 커널 모드에서 실행되는 코드에만 사용할 수 있는 주소 공간인 시스템 공간에 매핑됩니다. 커널 모드와 사용자 모드의 차이점에 대한 자세한 내용은 사용자 모드 및 커널 모드를 참조하세요.

경우에 따라 디바이스에는 커널 모드 디바이스 스택 외에 사용자 모드 디바이스 스택이 있습니다. 사용자 모드 드라이버는 WDF(Windows 드라이버 프레임워크)에서 제공하는 드라이버 모델 중 하나인 User-Mode 드라이버 프레임워크(UMDF)를 기반으로 하는 경우가 많습니다. UMDF에서 드라이버는 사용자 모드 DLL이고 디바이스 개체는 IWDFDevice 인터페이스를 구현하는 COM 개체입니다. UMDF 디바이스 스택의 디바이스 개체를 WDF DO(WDF 디바이스 개체 )라고 합니다.

다음 다이어그램은 USB-FX-2 디바이스에 대한 디바이스 노드, 커널 모드 디바이스 스택 및 사용자 모드 디바이스 스택을 보여줍니다. 사용자 모드 및 커널 모드 스택의 드라이버는 USB-FX-2 디바이스에서 전달되는 I/O 요청에 참여합니다.

사용자 모드 및 커널 모드 디바이스 스택을 보여 주는 다이어그램

모든 드라이버 개발자를 위한 개념

드라이버 스택