Programming/Kernel / Driver2008. 12. 3. 12:03

1. 드라이버의 작동 방식.

 운영체제는 하드웨어와 관련된 많은 동작을 수행하기 위해서 관련 서브 루틴 집합을 구현해 놓고있는데.
쉽게 말하면 드라이버는 이 서브루틴 집합을 담아두는 컨테이너라고 생각하면 된다.
이 컨테이너의 내용물은  DriverEntry, AddDevice, IRP(I/O request packet<- 앞으로 자주 나올놈이니 꼭 기억해두두록하자)처리를 위한 디스 패치 함수 등이 들어있다. 대부분의 드라이버는 몇 가지 종류의 IRP를 처리하는 디스패치 함수를 갖고있따.

WDM 드라이버 개발자는 이렇든 자신의 컨테이너에 포함시킬 기능들을 적절히 선택해서 조합하는 역활을 해야하는것이다.

                                    *컨테이너*

기본드라이버루틴          I/O컨트롤루틴            디스패치루틴

   DriverEntry               AdapterControl            DispatchPnp      
   AddDevice                    StartIO                      DispacthPower  
                                        Onlnterrupt                DispatchWmi
                                         DpcForlsr                  DispatchRead
                                                 ..                          DispatchWrite
                                                                                         ..

2. 어플리케이션의 작동 방식

"서브루틴들의 패키지(pacage of subroutines)" 모델인 드라이버를
"주프로그램과 조력자(main program and helper)" 모델인 일반 어플리케이션과 대비해서 생각해 보자.

ex>

 int main(int argc, char* argv[])
{
    printf("HELLO, WORLD");

    return 0;
}

이 프로그램은 main이라는 이름의 주프로그램과 보조 루틴들의 라이브러리로 구성되어있다.
보조 루틴중 하나인 printf는 표준 출력 파일에 메시지를 프린트한다.
주 프로그램이 들어있는 소스 모듈을 컴파일 하고, 이를 printf와 같은 보조 루틴들이 들어있는 런타임 라이버리와 링킹하고 나면, HELLO.EXE라는 실행 파일이 완성 될것이다.


* 다음은 어플리케이션에 대한 몇 가지 공통사항!

어플리케이션이 사용하는 특정 보조 루틴들은 정적 라이브러리에 포함되어 있고 linkage 에디터는 빌드 과정에서 이것들을 추출하게 된다. 일반적으로 printf같은것들이지. 일부 보조 루틴들은 시스템 DLL로부터 동적으로 링크되기도 한다. 이런 루틴들에 대해 linkage에디터는 실행 파일에 특별한 improt 레퍼런스를 삽입하여, 나중에 런타임 로더에서 이 레퍼런스가 실제 시스템 코드를 가리키도록 한다.
사실, 어플리케이션 프로그램에서 사용되는 모든 Win32 API는 동적으로 링크되어 잇기 때문에, Windows 프로그래밍에서 동적링크는 매우 중요한 개념임!!!


3. 디바이스 드라이버

Hello.EXE와 같이 드라이버도 역시 일종의 실행파일이란것을 알아두자!
파일 확장자는 ****.SYS이지만, 이 파일 구조는 다른 32비트 Windows나 콘솔 모드 어플리케이션과 동일함!!!!!<-
또한 HELLO.EXE와 마찬가지로 드라이버도 많은 보조 루틴을 사용하는데, 운영체제 커널이나 class driver나 다른 지원 라이브러리 에서 동적으로 링크된다. [ 또, 드라이버 파일도 심볼릭 디버깅 정보와 리소스데이터를 가지고있다. ]<- 심볼릭 디버깅등검색해보자!

  *드라이버에 대한 시스템의 역활

HELLO.EXE와는 달리, 드라이버는 main 프로그램을 포함하고 있지 않으며 대신!! 시스템의 판단에 따라 호출할 수 있는 서브 루틴들의 집합을 가지고있다.
서브루틴들은 드라이버나 정적 라이브러리나 운영체제 내에있는 여러 보조 루틴들을 사용할수 있지만. 드라이버는 자신의 하드웨어 외 다른것에는 관여하지 않는다.  그외 다른 부분은 모두 시스템이 담당하고있다.(예를들어 드라이버의 실행 시점 판단이라던가...)


 * 운영체제가 드라이버 내의 서브루틴을 호출하는 과정을 간단히 예를 들어보자!!

1) 사용자가 디바이스를 꽂으면, 시스템은 드라이버의 실행 파일을 가상 메모리에 올리고, DriverEntry 루틴을 호출!!  DriverEntry는 몇가지 작업을 하고 리턴~

2) PNP(Plug and Play) Manger는 드라이버의 AddDevice 루틴을 호출!! 역시 작업후 리턴~

3) PNP Manger가 드라이버에 IRP를 전송하면 디스패치 함수가 이를 처리하고 리턴!

4) 어플리케이션이 디바이스의 핸들을 열면 시스템이 또 다른 IRP를 전송하고, 디스패치 함수가 처리후 리턴!

5) 어플리케이션이 데이터를 읽으려고 시도하면, 시스템이 해당 IRP를 전송! 이에 대해 디스패치 루틴은 IRP를 큐에 저장하고 리턴!!!

6) 드라이버에 연결되어 있는 하드웨어 인터럽트에 신호를 보내서 이전의 I/O 오퍼레이션을 완료시킴.
   인터럽트 루틴에서는 DPC 스케줄링 등의 작업을 한후에 리턴!!!

7) DPC 루틴이 실행되어 5번작업에서 큐에 넣었던 IRP를 삭제하고 , 데이터를 읽도록 하드웨어를 작동시킨후 시스템으로 리턴~~~~~~~~~~

8) 시스템이 드라이버의 서브루틴들을 사용중. -ㅈ- 시간이 흐름.

9) 마침내, 유저가 디바이스를 제거. PNP Manger는 IRP를 드라이버로 전달하고 , 드라이버는 이를 처리한다음 리턴.
 운영체제는 드라이버의 Driver UNload 루틴을 호출해서 몇가지 일을 처리하고 리턴.
 최종적으로시스템은 가상메모리에서 드라이버 코드를 제거~~~~~~~~~~~~~~~~

 

4. 쓰레드와 드라이버 코드.

 드라이버가 어플리케이션과 다른점!
드라이버는 코드를 실행시키기 위해 시스템이 특별히 쓰레드를 생성시키지는 않는다는것!
대신 시스템이 드라이버의 서브루틴을 호출하기로 결정하면 그 순간 실행되고 있던 쓰레드 컨텍스트에서 드라이버 코드를 실행시킴!!!!

하드웨어 인터럽트가 발생하는 순간 모든 쓰레드들 중에서 어떤 것이 우연히 실행되고 있을지 알순 없지.
이것을 임의의(arbitrary) 쓰레드라고 부르며 "임의의 쓰레드 컨텍스트에서 실행된다" 라고 말함!

즉, 드라이버의 서브루틴을 호출하려 할 때, 대부분 임의의 쓰레드 컨텍스트에서 돌아가고 있을것이다.

예를들어, 자신의 드라이버의 ISR(Interrupt Service Routine)이 통제권을 가지는 순간 어떤 컨텍스트가 올지 모른다는거~

흔히 storage 드라이버의 경우에서 볼수있는데, 파일시스템 드라이버가 읽기/쓰기에 최종적인 책임을 지고 연관된 드라이버를 컨트롤 하는 형태로 되어있음!

하지만 항상 임의의 쓰레드 컨텍스트에서 드라이버 코드를 실행시키는것은 아님!

PsCreateSystemThread를 사용해서 자신의 시스템 쓰레드를 생성하거나 work item을 스케줄링해서 특정쓰레드를 요청할수도있음.

쓰레드가 임의적인지 아닌지가 왜중요하냐!


첫번째로, 드라이버는 임의의 쓰레드를 "블록킹" 해서는 안된다는거.

다른 쓰레드에 도움이 되는 작업을 수행한다고 해서 또다른 쓰레드를 중지시키는건 공평치 못하겠지?


두번째로, 드라이버가 IRP를 생성해서 다른 드라이버에게 이를 전달하는 경우인데
...

임의의 쓰레드에서는 비동기적 IRP만생성가능. 그러나 비임의 쓰레드에서는 동기적IRP도 생성가능하기때문이지.

동기적 방식에서는 I/O Manager는  IRP를 생성한 그 쓰레드의 컨텍스트에 IRP를 속하게 하고, 쓰레드가 종료되면 IRP를 자동으로 취소함.

 그러나 비동기적 IRP인경우,  I/O Manager는 이를 특정한 쓰레드에속하게 하지는 않음. 따라서 비동기적 IRP를 생성한 쓰레드는 드라이버에서 수행하는 I/O 오퍼레이션에 대해 직접적인 관계가 없으며, 이쓰레드가 종료됬다고 IRP를 취소시키지도 않는다는거지.



5. 시스템의 드라이버 로딩 방식

하드웨어가 플러그 앤 플레이(PNP) 를 지원하는지 여부에 따라 두 가지 조금 다른 방법을 사용한다.

1) 플러그 앤 플레이 디바이스는 시스템이 감지할 수 있는 전자 서명을 가지고 있음.
시스템 bus driver는 하드웨어의 존재 유무를 파악한 후, 어떤 종류의 하드웨어 인지 판단하기 위해 서명을 읽어옴
그 후 시스템은 레지스트리와 INF 파일을 이용해 자동으로 가장 적당한 드라이버를 로드하게 됨!!

2) Legacy 디바이스는 전자서명이 없다!!!  따라서 시스템이 자동으로 디바이스를 감지할수 없뜸.

그래서 사용자가 새 하드웨어 추가 마법사를 사용해서 검색해야함. 그러고나면 시스템은 레지스트리와 INF를 이용해 자동설치를한다!

Posted by skensita
Programming/Kernel / Driver2008. 12. 3. 11:58

WINDOWS XP 운영체제.

--------------------------------------------------------------------

어플리케이션     ->

                              WIN32 API 호출

WIN32서브시스템<-                                                                          유저모드

--------------------------------------------------------------------

                        ->                                                                         커널모드

                              시스템 서비스 인터페이스

                        <-

I/O MANAGE(디바이스 드라이버) -> HAL 호출

                            HAL(하드웨어 추상화 계층)

                                       -하드웨어-

---------------------------------------------------------------------



*WINDOWS 98/ME 하고 WINDOS 2000/XP 는 내부 동작이 전혀다름. 따라서 디바이스 개발도 다름.


*FILE SYSTEM DRIVER(파일시스템드라이버) : 명명된 파일(NAMED FILE)이 포함된 계층적 디렉토리 구조의 개념을 가진

표준 PC파일 시스템 모델을 로컬 하드디스크나 네트워크 연결에 대해 구현한다. 커널 모드 드라이버이다.


*LEGACY DEVICE DRIVER(레거시 디바이스 드라이버)  : 다른 드라이버의 도움 없이 하드웨어 디바이스를 직접적으로 컨트롤 하는 드라이버이다. 이 븐류에는 XP와 호환되는 NT 드라이버가 포함된다.


*WDM 드라이버 (윈도우즈 드라이버 모델)의 하부 드라이버 .


CLASS DRIVER - MICROSOFT에서 작성. 건드릴 필요없음.


MINI DRIVER - CLASS DRIVER와 함께 동작. 디바이스를 책임지고 있지만 클래스 드라이버의 서브루틴을 이용하며

클래스 드라이버는 하드웨어 관리를 맡고 있지만 많은 종속적 디바이스를 처리하기위해 MINIDRIVER를 역호출하게된다.

사용예-

(USB가 아닌 휴먼입력장치(HUMAN INPUT DEVICE:HID). 마으스, 키보드, 조이스틱, 게임 휠.

 스캐너와 카메라 같은 WINDOWS 이미지 수집 (WINDOWS IMAGE QCQUISITION:WIA) 디바이스.

 오디오,DVD,비디오 디바이스와 같은 스트리밍 디바이스와 멀티미디어 데이터 스트림

 비디오카드. 프린터. 배터리

 USB와 1394등 전통적이지 않은 버스를 사용하는 네트워크 인터페이스 디바이스. 이러한 디바이스에 대해서는 NDIS(NETWORK DRIVER INTERFACE SPECIFICATION)미니포트 드라이버를 만들어야한다. DDK 문서에서는 이를 "WDM LOWER EDGE"로 작성하라 권하고 있다. 이런 드라이버는 운영체제간에 호환성을 가지기가 어려우므로, 플랫폼 의존성을 해결하기 위해서는 작은 차이점을 가진 몇 가지 버전으로 만들도록 처음부터 계획해야한다. )



FILTER DRIVER - 경우에따라 마이크로 소프트가 제공하는 범용 드라이버가 완전한 요구사항과 맞아떨어지지 않을경우 필터드라이버를 작성해서 범용 드라이버의 작업을 수정하는것.



단일 WDM FUNCTION DRIVER - 이 드라이버는 기본적으로 독립적인 개체이고, 하드웨어를 제어하는 모든 세세한 부분을 처리.

사용예-

(스마트카드 리더, 디지털-아날로그 컨버터, 소유권확인태그 등등)


*SCSI(SMALL COMPUTER SYSTEM INTERFACE) 어댑터 : "SCSI MINIPORT" 드라이버를 사용하며, 다른 표준 커널 지원 함수를 전혀 사용하지 않는다. 이드라이버는 대신 SCSI-PORT.SYS 나 SCSIPORT.VXD에 의해 EXPORT된 특별한 API를 사용.


*네트워크 인터페이스 카드는 "NDIS MINIPORT 드라이버"를 사용. NDIS.SYS나 NDIS.VXD에의해 EXPORT된 특별한 API를 사용

Posted by skensita
Programming/Kernel / Driver2008. 12. 3. 11:55

WDM의 한계


1. WDM 드라이버를 작성하는 것은 로우레벨 작업이고, 복잡하다.

ex> 현재의 WDM 모델에서 드라이버 작성할 때  plug & play, power management 지원하려면,

     최소한 2000라인이 필요

     DDI(Device Driver Interface) 쓰기 어려움

2. DDI가 구식이다.

- 오직 퍼포먼스만을 위해 디자인되었고, 보안이나 사용 편의성이 고려되지 않아있다.

  그래서 DDI는 드라이버들에게 OS의 핵심적인 데이터 구조들을 곧바로 노출!
  →  MS는 이런 구조체들의 변경이 제한될 수 밖에 없었고, 드라이버가 시스템을 크래쉬 시킬 확률 증가!

 

- Versioning 지원이 없다.

3. 미니포트 모델이 너무 많다.

- Windows는 현재 10개 이상의 miniport  Model을 지원.

- 미니포트 모델마다 pnpdhk power management 다루는 방법이 다르다.

4. 멀티펑션 디바이스를 지원하는 작업이 너무 복잡하다.

두가지의 다른 미니포트 모델에 적용되는 멀티펑션 디바이스 지우너위해, 개발자는 WDM 버스 드라이버와 두개의 미니포트 드라이버 작성이 필요

5. 현재 드라이버 모델은 커널 레벨에서만 동작해야 한다.

- WDM과 미니포트 드라이버 모델 → 커널모드에서 실행

커널모드 드라이버는 운영체제의 일부로 대접받게 되므로, 시스템의 가상 메모리 영역 접근권한을 가짐.

이 때문에 커널모드 드라이버에서 에러가 발생하면 바로 시스템을 크래쉬 시키는 BSOD!!

6. 테스트 툴들이 쓰기 어렵다.

 

 

차세대 윈도우즈 드라이버 모델의 디자인 목적

1. 드라이버 모델은 심플하고 유연성(flexible)이 있어야 한다.

 

2. 드라이버 모델은 코어 운영체제 컴퓨넌트와 분리되어야만 한다.

 

3. 드라이버 모델은 일관성이 있어야 한다.

 

4. 드라이버 모델은 확장성이 있어야 한다.

 

5. 드라이버 모��유저모드를 지원해야 한다.

 

6.드라이버 모델은 고급 레벨의 언어를 지원해야 한다.

 

 

WDF(Windows Driver Framework)

* 프레임워크

- 커널모드 드라이버 프레임워크 (KMDF)

 

- 유저모드 드라이버 프레임워크 (UMDF)

- WDF는 Object-oriented, event-driven model을 제공

: Object는 드라이버를 위한 블록을 만드는 것으로 작업을 한다. 드라이버는 이 objects를 미리 정의된 인터페이스들을 통해 수정할 수 있다.

Event 집합은 object의 각각의 종류에 영향을 줄 수 있다. Framework는 각각의 event를 위한 default behavior가 정의되어 있다.
Device-specifice behavior를 위해, 드라이버는 defaults를 재정의할 수 있는 callback routine를 포함하고 있다.

 

- 커널모드 드라이버 프레임워크(Kernel-Mode Driver Framework; KMDF)

커널모드 드라이버를 만드는데 필요한 기본적 기능인 PnP, Power Management, I/O queue, DMA, WMI, synchronization 등 기본적인 기능을 구현, IEEE 1394, USB 같은 주요 버스들에 대한 지원도 한다.

 

운영체제 커널의 일부분으로 포함된 것이 아니라, 별도로 제공되는 독립된 라이브러리이다.

 

커널모드 드라이버 프레임워크에서 인터페이스는 미래에도 가능한 한 드라이버의 독립성을 추구하도록 디자인되어 있다. 만약 드라이버가 크래쉬되면, OS는 시스템을 멈추거나 전체를 크래쉬하지 않고 복구하거나 드라이버엥 의해 할당된 리소스들을 클린업한다.

- 유저모드 드라이버 프레임워크(User-Mode Driver Framework)

Pnp, Power management, 비동기 I/O 지원을 포함하는 커널모드 프레임워크 기능의 일부분을 구현한다.

DMA 수행, 인터럽트 지원, nonpaged 풀 등의 커널모드 리소스를 사용하지 않는 드라이버들은 유저모드에서 실행될 수 있다.

 

네트워크와 연결된 디바이스들(network-connected devices)을 위한 드라이버와 PMP, 카메라, 핸드폰 같은 USB 디바이스들을 위한 드라이버를 만들 수 있다.

 

UMDF는 비스테이서 지원된다. XP에서 지원은 정책결정중이라던데..이부분은 찾아봐야하겠다.

[출처] WDM과 WDF

Posted by skensita
Programming/Kernel / Driver2008. 12. 3. 11:54

WDM 드라이버 기본 구조

 

디바이스 드라이버 : 운영체제가 하드웨어 디바이스와 관련된 다양한 동작을 하기 위해 호출할 수 있는 서브루틴의 집합을 담을 수 있는 컨테이너의 개념.

 

디바이스 드라이버 계층화

 

WDM은 일정한 규격에 맞게 드라이버의 레이어가 생성되도록 한다.

DO(Device Object)들은 시스템이 소프트웨어의 하드웨어 관리를 돕기 위해 만들어 낸 자료 구조.

 

스택의 가장 낮은 레벨의 디바이스 객체는 PDO(Physical device object)라고 한다.

디바이스 객체의 가운데쯤 있는 것이 FDO(Functional device Object)라고 불리우는 객체이다.

 

FDO의 위쪽과 아래쪽에는 filter device object들의 모임이 존재할 것이다. FDO의 위에 위치한 객체는 상위필터(upper filter)라고 하고, 아래에 위치한 객체(PDO보다는 위에 있지만..)는 하위필터(lower filter)라고 한다.

 

Filter device object FiDO라는 약어로 사용하는 것을 볼 수 있지만 공식적인 것이 아니다. 하지만 FiDO라고 해도 알아듣도록 하자.

 

운영체제의 PnP 매니저 컴포넌트는 디바이스 드라이버의 요청에 의해 디바이스 객체의 스택을 형성한다.

 

Bus에 대한 드라이버의 역할 중에 하나는 bus에 부착된 디바이스를 나열하고, 그들 각각에 대한 PDO를 생성한다. PDO를 생성한 다음 PnP 매니저는 filter driver FDO를 찾기 위해 레지스트리 데이터베이스를 참고한다. 레지스트리 엔트리는 스택에 나타날 드라이버의 순서를 정한다. 그 결과 가장 낮은 레벨의 filter driver를 로딩하고 그것의 AddDevice 함수를 호출 함으로써 PnP가 시작된다.

AddDevice filter driver를 만들고 filter driver와 드라이버 사이의 수평 링크를 생성한다. 그리고 나서 PDO filter driver에 연결한다.

 

계층화의 목적.

디바이스에 영향을 주는 오퍼레이션에 대한 요청 각각은 IRP(I/O Request Packet)를 사용한다.

IRP는 디바이스에 대해 최상위에 위치한 드라이버로 정상적으로 보내지고, 다른 드라이버로 스택을 타고 내려올 수 있다. 각 레벨에서 드라이버는 IRP로 무엇을 할 것인가를 결정한다.

 

하나의 하드웨어를 위해 스택을 점유하고 있는 다양한 드라이버들은 각기 다른 역할을 수행한다.

FDO는 디바이스를 관리하고, bus driver(PDO)는 디바이스와 컴퓨터 사이의 연결을 관리한다.

Filter driver IRP의 스트림을 감시하거나 수정하는 역할을 한다.

 

PDO FDO와 완전히 다른 작업을 수행한다. FDO IRP PDO에게 내려보냄으로써 PDO에게 어떤 작업을 위임한다”.

 

시스템이 드라이버를 로드하는 방법

 

재귀적 계산(enumeration)

 

PnP 매니저는 실제로 존재하지 않는 루트(root)” 버스에 대한 빌트-(built-in, 내장)드라이버를 가지고 있다. PCI 같은 Primary hardware bus를 포함해서 루트 버스 드라이버는 레지스트리로부터 컴퓨터에 대한 정보를 얻는다.

 

Primary bus에 대한 function driver는 자신의 하드웨어를 전기적으로 나열(enumerate)한다.

PCI 버스는 각각의 부착된 디바이스에 대한 특별한 구성 공간(디바이스에 대한 디스크립션과 리소스 요구사항이 포함되어 있다)을 액세스하는 방법을 제공한다.

Bus driver가 하드웨어를 나열할 때 버스 드라이버는 일반적인 function driver로 가장하여 작동하다가 하드웨어를 감지한 후에는 드라이버의 역할이 바뀌게된다(감지된 하드웨어에 대한 새로운 PDO)를 생성하게 된다.

 

레지스트리의 역할

 

레지스트리 데이터베이스가 드라이버를 로드하고 디바이스를 구성하는 과정에서 결정적인 역할을 한다. 그러므로 어떤 레지스트리 키들이 관련되어 있고 그것들이 무엇을 담고 있는지 설명한다.

 

세가지 다른 레지스트리 키(하드웨어 키, 클래스 키, 서비스 키)들은 구성(configuration)과 관계가 있다. 저 세가지의 이름은 적절한 이름이 아니다.

하드웨어 키는 단일 디바이스에 대한 정보를 포함한다. (인스턴스 키라는 이름을 사용하기도 한다.)

클래스 키는 같은 타입의 모든 디바이스들과 관련이 된다.

서비스 키는 드라이버들에 대한 정보를 포함한다. (소프트웨어 키라는 이름을 사용하기도 한다.)

 

하드웨어 키 :

레지스트리의 HKEY_LOCAL_MACHINE\System\CurrentSet\Enum 서브키에서 나타난다.

Enum키 아래에 있는 첫번째 레벨에 위치한 서브키들은 시스템에 있는 다른 버스 나열자와 대응된다. 모든(과거 또는 현재) USB 디바이스들의 디스크립션이 …\Enum\USB 서브키안에 존재한다.

ClassGUID는 디바이스 클래스를 식별케 해주는 globally unique indentifier(GUID)의 고유 ASCII표현방식이며 디바이스의 클래스키에 대한 포인터이다.

Service서비스 키에 대한 포인터이다.

 

클래스 키:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class에서 나타난다.

클래스 키들의 키 이름은 마이크로소프트에서 지정한 GUID이다.

각 디바이스는 클래스 키 아래에 자신의 서브키(0000 같은)를 가지고 있다. 이 키의 이름은 디바이스 하드웨어 키에 있는 드라이버 값이다.

 

서비스 키:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services에 나타난다.

이것은 드라이버의 실행 가능한 파일이 디스크에 놓인 위치를 나타내고 드라이버가 로드되는 방식을 제어하는 다른 매개 변수들을 포함한다.

서비스키에 대한 참고링크 : http://support.microsoft.com/kb/103000

 

 

드라이버 로딩의 순서

 

PnP 매니저가 새로운 디바이스를 접하게 되면 하드웨어와 클래스 키를 열고, 드라이버를 로드하기 위해 다음과 같은 순서로 작동한다.

1.     디바이스에 대한 하드웨어 키에서 지정된 하위 필터 드라이버. LowerFilters 값은 REG_MULTI_SZ 타입이기 때문에 하나 이상의 드라이버를 지정할 수 있다.

2.     클래스 키에서 지정된 하위 필터 드라이버, 또다시 하위 필터 드라이버, 이것들이 LowerFilter 값의 데이터 스트링에 나타난 순서대로 로드된다.

3.     하드웨어 키에서 Service 값에 의해 지정된 드라이버

4.     하드웨어 키에서 지정된 상위 필터 드라이버 그리고 UpperFilters 데이터 스트링에 나타난 순서

5.     마찬가지로 또다시 클래스 키에서 지정된 상위 필터 드라이버 그리고 UpperFilters 데이터 스트링에 나타난 순서대로 로딩한다.

 

시스템이 드라이버를 로드한다고 말할 때 이것은

드라이버의 이미지를 가상 메모리로 맵핑하고,

재배치 가능한 레퍼런스들을 수정하며,

드라이버의 메인 엔트리 포인트를 호출하는 것

을 의미한다. 메인 엔트리는 보통 DriverEntry라고 부른다.

 

디바이스 객체가 상호 관계를 가지는 방법

 

디바이스 객체 스택의 트리에서 IRP가 반드시 PDO에서 꼭대기의 filter driver object로 흘러가야 한다는 것을 의미하지 않는다. 간단하게 말하면 트리의 구조에 있는대로 다음의 드라이버객체로 IRP를 보낼 수도 있고 보내지 않을 수도 있다는 이야기이다.

 

이외에 설명이 더 있는데 이 부분은 잘 이해가 안된다.. L

 

 

드라이버 객체

 

I/O 매니저는 각각의 디바이스 드라이버를 나타내기 위해 드라이버 객체 자료 구조를 사용한다.

이 드라이버 객체 자료 구조는 부분적으로 불투명(opaque)하다. _DRIVER_OBJECT에서 강조되지 않은 부분이 그에 해당한다.

 

typedef struct _DRIVER_OBJECT{

   CSHORT Type;

   CSHORT Size;

   PDEVICE_OBJECT DeviceObject;

   ULONG Flags;

   PVOID DriverStart;

   ULONG DriverSize;

   PVOID DriverSection;

   PDRIVER_EXTENSION DriverExtension;

   UNICODE_STRING DriverName;

   PUNICODE_STRING HardwareDatabase;

   PFAST_IO_DISPATCH FastIoDispatch;

   PDRIVER_INITIALIZE DriverInit;

   PDRIVER_STARTIO DriverStartIo;

   PDRIVER_UNLOAD DriverUnload;

   PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];

} DRIVER_OBJECT, *PDRIVER_OBJECT;

 

헤더는 구조체를 DRIVER_OBJECT라는 타입명으로 정의한다. 또한 포인터 타입(PDRIVER_OBJECT)을 선언하고 구조체 태그(_DRIVER_OBJECT)를 할당한다.

 

드라이버 객체 구조체의 액세스 가능한 필드들에 대해 간단하게 알아본다.

DeviceObject(PDEVICE_OBJECT) : 드라이버에 의해 관리되는 각각의 디바이스에 대한 디바이스 객체 자료 구조의 리스트를 가리킨다.

DriverExtension(PDRIVER_EXTENSION) : 오직 AddDevice(PDRIVER_ADD_DEVICE) 멤버만을 액세스 할 수 있는 작은 하위 구조체를 가리킨다. 그 안에서 드라이버가 드라이버 객체를 만들어 내는 함수에 대한 포인터이다.

HardwareDatabase(PUNICODE_STRING) : 디바이스에 대한 하드웨어 데이터베이스 레지스트리 키의 이름이 들어 있는 문자열을 나타낸다. \Registry\Machine\Hardware\Description\System과 같은 이름이다.

FastIoDispatch(PFAST_IO_DISPATCH) : 파일 시스템과 네트워크 드라이버가 익스포트(export)하는 함수 포인터들의 테이블을 가리킨다.

DriverStartIo(PDRIVER_STARTIO) : 직렬화(serialize) I/O 요청을 처리하는 드라이버 함수를 가리킨다.

DriverUnload(PDRIVER_UNLOAD) : 드라이버의 클린업 함수를 가리킨다.

MajorFunction(PDRIVER_DISPATCH의 배열) : I/O 요청 타입의 각각을 처리하는 드라이버의 함수에 대한 포인터들의 테이블이다.

 

디바이스 객체

 

다음은 DEVICE_OBJECT의 자료 구조이다.

 

typedef struct _DEVICE_OBJECT {
  CSHORT  Type;
  USHORT  Size;
  LONG  ReferenceCount;
  PDRIVER_OBJECT  DriverObject;
  PDEVICE_OBJECT  NextDevice;  PDEVICE_OBJECT  AttachedDevice;
  PIRP  CurrentIrp;
  PIO_TIMER  Timer;
  ULONG  Flags;
  ULONG  Characteristics;

  __volatile PVPB  Vpb;
 
PVOID  DeviceExtension;
  DEVICE_TYPE  DeviceType;
  CCHAR  StackSize;  union {
    LIST_ENTRY  ListEntry;
    WAIT_CONTEXT_BLOCK  Wcb;
  } Queue;
  ULONG  AlignmentRequirement;
  KDEVICE_QUEUE  DeviceQueue;
  KDPC  Dpc;
  ULONG  ActiveThreadCount;
  PSECURITY_DESCRIPTOR  SecurityDescriptor;
  KEVENT  DeviceLock;
  USHORT  SectorSize;
  USHORT  Spare1;
  PDEVOBJ_EXTENSION  DeviceObjectExtension;
  PVOID  Reserved;
} DEVICE_OBJECT, *PDEVICE_OBJECT;

 

DEVICE_OBJECT에 대한 자세한 내용 : http://msdn.microsoft.com/en-us/library/aa491677.aspx

 

출처 : http://wert.egloos.com/4502911

 

Posted by skensita
Programming/Kernel / Driver2008. 11. 30. 16:35


WDM 기반 USB 지원 드라이버 제작
Posted by skensita