Windows XP 에서의 장치관리자 : Device Driver에 관하여 Sep 5, 2008. CHONBUK NATIONAL UNIVERSITY Prof. Woonchul Ham 2018-09-22
Device Driver 응용사례 : UsbBulk.sys Application Program 개요 장치관리자란? Device Driver 작업환경은? Driver 의 구조 Plug & Play Device Driver 응용사례 : UsbBulk.sys Application Program 2018-09-22
내 컴퓨터->속성-> 하드웨어->장치관리자 장치관리자란? 내 컴퓨터->속성-> 하드웨어->장치관리자 2018-09-22
장치관리자란? (USB) 이곳을 클릭 2018-09-22
장치관리자란? (USB) 2018-09-22
장치관리자란? (USB) 2018-09-22
장치관리자란? (USB) USBSTOR.SYS 파일을 이해하고 만들어 본다. 이러한 *.SYS 파일이 바로 Device Driver 이며, 이 동적라이브러리를 통하여 응용프로그램(*.exe) 이 OS 와의 대화를 통하여 하드웨어를 접근할 수 있게 되는 것이다. 2018-09-22
Hardware Abstraction layer(HAL) 장치드라이버란? (USB) Applications Win32 API User Mode Kernel Mode Other Kernel Mode Driver Operating System Kernel File System Drivers Hardware Abstraction layer(HAL) Hardware 2018-09-22
5. Device Driver 응용사례 : UsbBulk.sys 1. 장치관리자란? 2. Device Driver 작업환경은? 3. Driver 의 구조 4. Plug & Play 5. Device Driver 응용사례 : UsbBulk.sys 6. Application Program 2018-09-22
2. Windows Device Driver Tool kit 설치 1. Windbg 설치 2. Windows Device Driver Tool kit 설치 3. NULL Modem Cable 연결 4. Target Computer, Host Computer 2018-09-22
2. Device Driver 작업환경은? : Windbg 설치 먼저 두 대의 컴퓨간에 널 모뎀 케이블과 하이퍼터미널을 이용하여 통신여부를 파악한다. (buadrate, no hardware로 세팅하여 확인하며, 또한 파일 전송 여부가 잘되는 지도 확인 하면 좋을 듯) Target 컴퓨터의 OS 시스템이 설치된 하드디스크 (C:) 폴더에 있는 BOOT.INI 파일의 내용을 다음과 같이 수정한다. 물론 baudrate와 comport값을 적절하게 세팅하여야 한다. [boot loader] timeout=10 default=multi(0)disk(0)rdisk(0)partition(1)\WINNT [operating systems] multi(0)disk(0)rdisk(0)partition(1)\WINNT="Microsoft Windows 2000 Professional" /fastdetect /noguiboot multi(0)disk(0)rdisk(0)partition(1)\WINNT="MS Win 2000 Professional-Prof.Ham" /fastdetect /noguiboot /debug /debugport=com1 /baudrate=115200 2018-09-22
2. Device Driver 작업환경은? : Windbg 설치 Host Computer에 Windbg 6.0 버전을 설치한다 Target 컴퓨터에서 작성된 *.pdb 파일을 Host computer의 c:\winnt\ 아래 (중요?? : c:\winnt\symbolham)에 폴더를 만들어 복사한다. Target 컴퓨터에서 작성된 *.c, *.cpp 파일을 Host computer의 c:\winnt\ 아래(중요??: c:\winnt\symolsourceham)에 폴더를 만들어 복사한다. Null Modem Cable을 연결하고 난후, Host Computer의 Windbg를 수행한다 Windbg의 FILE->Symbol File Path와 FILE->Source File Path를 4, 5에서의 폴더로 세팅한다 Windbg의 Kernel Debug를 선택한다 이제 Target Computer를 부팅한다. Windbg의 Command 창에 디벅메시지가 나타나는지를 살펴본다 2018-09-22
2. Device Driver 작업환경은? : Windbg 설치 가급적 Windbg의 Debug->Source Mode가 체크되어 있는 지를 확인한다 Windbg의 Command 창에 " LM "명령어를 입력하여, 현재 Load된 Module들에 대한 상태들을 살펴본다. 이때 분석하고자 하는 드라이버들에 대한 Symbol들이 잘 올라가 있는 지를 살펴본다 12 번이 여의치 않은 경우 " .reload " 명령어를 입력하여, 새로운 Symbol들로 다시 재 로드하여, 원하는 드라이버 루틴에 대한 *.pdb 파일들이 제대로 Loading 되었는 지를 살펴본다 WIndbg 의 Command 창에서의 명령에 대하여서는 Windbg의 Help->Contents를 크릭하여 도움말을 열고 난후 Reference->Debugger Commands 부분을 읽어 보면 좋을 듯 하다. 2018-09-22
2. Device Driver 작업환경은? : Windbg 설치 16. Windbg의 Command 창에 " x i8042prt!* " 명령어를 입력하여, i8042prt.sys 드라이버 모듈과 관련된 Symbols들을 살펴보기를 바란다. \ Windbg의 Command 창에 " bp i8042prt!I8042KeyboardInterruptService* " 명령어를 입력하여, Debug Break Point를 세팅한 후, 그 결과를 체크하기 위하여, " BL "명령어를 입력하여 본다. " BC #", " BD # ", " BE # " 명령어는 해당되는 Break Point를 지우거나, Disable, Enable 시킨다 Host Computer에서 Break 하기 위하여서는 Debug->Break을 선택하면 된다 2018-09-22
5. Device Driver 응용사례 : UsbBulk.sys 1. 장치관리자란? 2. Device Driver 작업환경은? 3. Driver 의 구조 4. Plug & Play 5. Device Driver 응용사례 : UsbBulk.sys 6. Application Program 2018-09-22
Kernel Mode Client Driver Layered Driver Architecture Applications User Mode Client Driver Win32 API User Mode Kernel Mode Kernel Mode Client Driver Operating System Kernel File System Drivers Class Driver Port Driver Hardware Bus driver 2018-09-22
2018-09-22
5. Device Driver 응용사례 : UsbBulk.sys 1. 장치관리자란? 2. Device Driver 작업환경은? 3. Driver 의 구조 4. Plug & Play 5. Device Driver 응용사례 : UsbBulk.sys 6. Application Program 2018-09-22
2018-09-22
5. Device Driver 응용사례 : UsbBulk.sys 1. 장치관리자란? 2. Device Driver 작업환경은? 3. Driver 의 구조 4. Plug & Play 5. Device Driver 응용사례 : UsbBulk.sys 6. Application Program 2018-09-22
파일의 구성 Bulkusb.c Bulkpnp.c Busbdbg.c Ioctlblk.c Ocrwblk.c Bulkpwr.c 2018-09-22
Sources파일 TARGETNAME=secbulk TARGETTYPE=DRIVER DRIVERTYPE=WDM TARGETPATH=obj TARGETLIBS=$(DDK_LIB_PATH)\usbd.lib USE_MAPSYM=1 SOURCES= \ BulkUsb.rc \ BusbDbg.c \ BulkUsb.c \ SBulkPnP.c \ BulkPwr.c \ IoctlBlk.c \ OcrwBlk.c 2018-09-22
Bulkusb.c : DriverEntry() NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { …… // Create dispatch points for create, close, unload DriverObject->MajorFunction[IRP_MJ_CREATE] = BulkUsb_Create; DriverObject->MajorFunction[IRP_MJ_CLOSE] = BulkUsb_Close; DriverObject->DriverUnload = BulkUsb_Unload; // User mode DeviceIoControl() calls will be routed here DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = BulkUsb_ProcessIOCTL; // User mode ReadFile()/WriteFile() calls will be routed here DriverObject->MajorFunction[IRP_MJ_WRITE] = BulkUsb_Write; DriverObject->MajorFunction[IRP_MJ_READ] = BulkUsb_Read; // routines for handling system PNP and power management requests DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = BulkUsb_ProcessSysControlIrp; DriverObject->MajorFunction[IRP_MJ_PNP] = BulkUsb_ProcessPnPIrp; DriverObject->MajorFunction[IRP_MJ_POWER] = BulkUsb_ProcessPowerIrp; ….. CreateFile() CloseFile() DeviceIOControl() WriteFile() ReadFile() PowerManager IoCallDriver() 2018-09-22 PnPManager
Bulkusb.c 장치가 장착될 경우에 PnP Manager에 의하여 불리어 진다. // DriverObject->DriverExtension->AddDevice = BulkUsb_PnPAddDevice; BULKUSB_KdPrint( DBGLVL_DEFAULT,("exiting DriverEntry (%x)\n", ntStatus)); return ntStatus; } 장치가 장착될 경우에 PnP Manager에 의하여 불리어 진다. 2018-09-22
Bulkusb.c : BulkUsb_ProcessSysControlIrp NTSTATUS BulkUsb_ProcessSysControlIrp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; irpStack = IoGetCurrentIrpStackLocation (Irp); deviceExtension = DeviceObject->DeviceExtension; stackDeviceObject = deviceExtension->TopOfStackDeviceObject; BulkUsb_IncrementIoCount(DeviceObject); BULKUSB_ASSERT( IRP_MJ_SYSTEM_CONTROL == irpStack->MajorFunction ); IoCopyCurrentIrpStackLocationToNext(Irp); ntStatus = IoCallDriver(stackDeviceObject, Irp); BulkUsb_DecrementIoCount(DeviceObject); return ntStatus; } Next Lower Driver Drivers that do not support WMI by registering as a WMI data provider must pass IRP_MJ_SYSTEM_CONTROL requests to the next lower driver. 2018-09-22
Bulkusb.c : BulkUsb_Read NTSTATUS BulkUsb_Read( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { NTSTATUS ntStatus = BulkUsb_StagedReadWrite(DeviceObject, Irp, TRUE); // false to write, true to read return ntStatus; } 2018-09-22
Maximum TransferSize:4096 Bulkusb.c : BulkUsb_StagedReadWrite NTSTATUS BulkUsb_StagedReadWrite( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN BOOLEAN Read ) { PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension; … if ( Irp->MdlAddress ) { // could be NULL for 0-len request totalLength = MmGetMdlByteCount(Irp->MdlAddress); } if ( totalLength <= deviceExtension->MaximumTransferSize ) { // for short or zero-len transfers, no need to do the staging; do it in a single request return BulkUsb_SingleUrbReadWrite( DeviceObject, Irp, Read ); } } Maximum TransferSize:4096 2018-09-22
Bulkusb.c : BulkUsb_SingleUrbReadWrite()-1 NTSTATUS BulkUsb_SingleUrbReadWrite( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN BOOLEAN Read) { … Irp->IoStatus.Information = 0; siz = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER); irpStack = IoGetCurrentIrpStackLocation (Irp); fileObject = irpStack->FileObject; pipeHandle = fileObject->FsContext; ….. if ( Irp->MdlAddress ) { // could be NULL for 0-len request totalLength = MmGetMdlByteCount(Irp->MdlAddress); } urb = BulkUsb_BuildAsyncRequest(DeviceObject, Irp, pipeHandle, Read); deviceExtension->BaseUrb = urb; nextStack = IoGetNextIrpStackLocation(Irp); nextStack->Parameters.Others.Argument1 = urb; 2018-09-22
Bulkusb.c : BulkUsb_SingleUrbReadWrite()-2 nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; IoSetCompletionRoutine( Irp, // irp to use BulkUsb_SimpleReadWrite_Complete, // routine to call when irp is done DeviceObject, // we pass our FDO as context to pass routine TRUE, // call on success TRUE, // call on error TRUE); BulkUsb_IncrementIoCount(DeviceObject); ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp ); return ntStatus; } 2018-09-22
Data Structure : IRP typedef struct _IRP { . . PMDL MdlAddress; ULONG Flags; union { struct _IRP *MasterIrp; PVOID SystemBuffer; } AssociatedIrp; IO_STATUS_BLOCK IoStatus; .. PDRIVER_CANCEL CancelRoutine; PVOID UserBuffer; } Tail; } IRP, *PIRP; Pointer to an MDL describing a user buffer for an IRP_MJ_READ or IRP_MJ_WRITE request if the driver set up its device object(s) for direct I/O . AssociatedIrp.SystemBuffer Pointer to a system-space buffer for one of the following: (1) a transfer request to a driver that set up its device object(s) requesting buffered I/O; (2) an IRP_MJ_DEVICE_CONTROL request, (3) an IRP_MJ_INTERNAL_DEVICE_CONTROL request with an I/O control code that was defined with METHOD_BUFFERED 2018-09-22
Data Structure : IO_STACK_LOCATION typedef struct _IO_STACK_LOCATION { UCHAR MajorFunction; UCHAR MinorFunction; UCHAR Flags; UCHAR Control; union { // Parameters for IRP_MJ_CREATE struct { PIO_SECURITY_CONTEXT SecurityContext; ULONG Options; USHORT POINTER_ALIGNMENT FileAttributes; USHORT ShareAccess; ULONG POINTER_ALIGNMENT EaLength; } Create; // Parameters for IRP_MJ_READ struct { ULONG Length; ULONG POINTER_ALIGNMENT Key; LARGE_INTEGER ByteOffset; } Read; …. PDEVICE_OBJECT DeviceObject; PFILE_OBJECT FileObject; . . } IO_STACK_LOCATION, *PIO_STACK_LOCATION; 2018-09-22
Data Structure : FILE_OBJECT Accessible Fields PDEVICE_OBJECT DeviceObject Pointer to the device object on which the file is opened. PVOID FsContext Pointer to whatever optional state a driver maintains about the file object; otherwise, NULL. PVOID FsContext2 Pointer to whatever additional state a driver maintains about the file object; otherwise, NULL. UNICODE_STRING FileName Is the name of the file opened on the device, or the Length of the string is zero if the device represented by DeviceObject is being opened. 2018-09-22
2018-09-22
2018-09-22
2018-09-22
5. Device Driver 응용사례 : UsbBulk.sys 1. 장치관리자란? 2. Device Driver 작업환경은? 3. Driver 의 구조 4. Plug & Play 5. Device Driver 응용사례 : UsbBulk.sys 6. Application Program 2018-09-22
아지시스템에서 제공하는 2410 관련 CD 에 들어 있는 rwbulk.exe ( Web Disk 에서 다운 로드 할 것) Application Program 아지시스템에서 제공하는 2410 관련 CD 에 들어 있는 rwbulk.exe ( Web Disk 에서 다운 로드 할 것) MBA 2440 보드를 호스트 컴퓨터와 연결 호스트컴퓨터에서 DNW.exe 를 가동하고 MBA 를 리셋한후 18번 메뉴를 선택한 후에 다시 1번 메뉴를 세팅하여 target MBA 2440 보드의 USB Client (Device) 기능을 발휘시킨다. 호스트 컴퓨터의 rwbulk.exe 를 가동한 후 “rwbulk –r 128” 을 수행하여 타겟 MBA2440 으로부터 USB 를 통하여 data 를 전송받아본다. 3. 단계가 잘 되지 않을 경우, dnw.exe 의 USB Port-> Rx Test 를 클릭하여 타겟 MBA2440 으로부터 USB 룰 통하여 data 가 잘 전송되는지 체크하여본다. 2018-09-22
Application Program DNW.exe 프로그램의 작동: USB Port-> Rx Test 2018-09-22
Application Program Rwbulk.exe 프로그램의 작동: rwbulk –r 128 2018-09-22
Application Program Rwbulk.exe 프로그램이 작동될 때, dnw.exe 도 MBA2440 보드가 USB Device 로 작동되게 하기 위하여 가동되어야 하며, 여기서 18번 메뉴와 이에 대한 1번 서브를 선택하여야 한다. 이러한 처리가 있어야만 MBA2440 보드가 usb Device 로 가동되며, 따라서 이 때 dnw.exe 의 USB Port -> Rx Test 를 수행하여 MBA2440 보드의 USB Device 기능이 잘 발휘되는가를 살펴본다. 다음 그림에서는 SECBULK.SYS 와 관련하여 두개의 장치가 가동중임을 알 수 있으며, 하나는 DNW.exe 와 다른 하나는 rwbulk.exe 와 SECBULK.SYS 와 연계하여 작동하고 있음을 보여주고 있다. USBPDO-12 2018-09-22
Application Program USB Client 의 장치명 2개가 사용되고 있다. 2018-09-22
rwbulk.c 에 대하여 MS Visual C 로 작동시키기 위한 절차 Application Program rwbulk.c 에 대하여 MS Visual C 로 작동시키기 위한 절차 rwbulk.c 를 MS Visual C tool을 이용하여 open 한다. Visual C 상황에서 Build->Rebuild ALL를 수행하여 본다. 이 후 Project 를 만들 것이냐? 물음이 들어오면 yes를 응답한다. 다시 Visual C 상황에서 Build->Rebuild ALL를 수행하여 본다. 당연히 ERROR 가 발생된다. ERROR 에 대처한 다음 절차를 밟는다 Tools->Options 를 선택하여 Build Directory 탭을 선정하고 include files 에 대한 directory를 D:\WINDDK\2600.1106\INC\DDK\WXP 로 세팅한다. Project->Settings를 클릭하고나서 나타나는 대화상자에서 Link 탭을 선정한다. 그리고 나서 Object/Library modules 부분에 setupapi.lib usbd.lib를 추가 한다. Tools->Options 를 선택하여 Build Directory 탭을 선정하고 library files 에 대한 directory를 D:\WINDDK\2600.1106\LIB\WXP\I386로 세팅한다. 2018-09-22
rwbulk.c 에 대하여 MS Visual C 로 작동시키기 위한 절차 Application Program rwbulk.c 에 대하여 MS Visual C 로 작동시키기 위한 절차 Project->Settings 의 Debug 탭을 선택하고 Program Argument 에 “ –r 128” 을 입력한다. Rwbulk.c 의 main() 함수의 parse() 부분에 debug break 을 세팅하고 나서 build->Start debug 을 수행하면서 디버깅하여 본다. 2018-09-22
Application Program 2018-09-22
Application Program 다음과 같이 기존의 main() 루틴에 dump() 를 추가하여 USB Device 로 부터 읽어온 내용을 command 창에 나타낸다. … printf("<%s> R (%04.4d) : request %06.6d bytes -- %06.6d bytes read\n", inPipe, i, ReadLen, nBytesRead); //HAM printf("Dumping read buffer\n"); dump( pinBuf, nBytesRead ); if (fWrite) { ….. 2018-09-22
Application Program 2018-09-22
Application Program TIP : 디버깅 모드에서 작동시키면 작동이 되지 않음을 유의하시기 바랍니다. 따라서 USB read 작동시는 디버깅 상태에서 Test 가 되지 않음을 유념하시기 바랍니다. 2018-09-22
- END - 2018-09-22