윈도우 커널모드 드라이버 64비트 포팅 월간 마이크로소프트웨어 2005.9 김성현 2006.1.21.

Slides:



Advertisements
Similar presentations
한국마이크로소프트 Microsoft Confidential. 상세 결과테스트 결과 SMB 2 의 성능이 Windows Server 2008 Beta 3 기준으로 Windows Server 2003 SP1 (SMB 1) 에 비해 9% 이상 향상된 결과를 보임 Microsoft.
Advertisements

1 구조체 윤 홍 란 컴퓨터 프로그래밍 2 구조체 정의  구조체란 ? o 서로 다른 형의 변수들을 하나로 묶어주는 mechanism. (cf. 배열 : 같은 형의 변수들을 하나로 묶어주는 mechanism) o 예 : 카드의.
.Net History. Visual Studio.Net 2002 /.Net Framework 1.0 제품의 버전 / 특징 2002 년 - Visual Studio.Net 2002 /.Net Framework 1.0 첫 통합 개발 환경 - C# 언어 등장 (C# 1.0)
Windows 디바이스 드라이버 Update 정 우식 개발부장 ㈜열린기술 내용  드라이버 개발자 입장에서 본 XP  XP DDK Update  64- 비트 이슈  디바이스 설치  USB 드라이버 스택  디버깅 및 기타 도구들.
Android 프로그램개발 환경. 학습 목표 ■ 교육 목표  JDK 설치  JDK 환경 설정  Eclipse 설치  Android SDK 설치  ADT Plug-in 설치  Android Virtual Device(AVD) 설치  Android 예제 프로그램.
컴퓨터와 인터넷.
1. 준비 사항 설치할 컴퓨터의 사양 확인 하드웨어와 Windows Server 2003의 호환성 확인
컴퓨터 운영체제의 역사 손용범.
Let’s Speak English Well
USB Interface study 결과
컴퓨터프로그래밍 1주차실습자료 Visual Studio 2005 사용법 익히기.
김태원 심재일 김상래 강신택. 김태원 심재일 김상래 강신택 인터넷 통신망의 정보를 제공하는 서비스 인터넷의 자원 및 정보는 NIC가 관리 IP주소 또는 도메인으로 정보 검색 이용자 및 통신망 관한 정보를 제공.
Image & Video processing
제 2장 컴퓨터 구조.
제14장 동적 메모리.
Power Java 제3장 이클립스 사용하기.
1. Windows Server 2003의 역사 개인용 Windows의 발전 과정
마이크로소프트 64bit 윈도우 컴퓨팅 구조와 로드맵
SAS Foundation Client 9.4 설치 가이드
Windows CE 시스템 개발 환경 구축.
Network Lab. Young-Chul Hwang
제 9 장 구조체와 공용체.
Power Java 제2장 자바 개발 도구.
08. 디바이스 드라이버의 읽기와 쓰기 김진홍
Chapter 03. 소켓 주소 구조체 다루기.
2007. Database Term Project Team 2 윤형석, 김희용, 최현대 우경남, 이상제
TMS320F2812의 GPIO의 이해.
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 12. 포인터의 이해.
기상연구소 응용 프로그램 (MM5/MPP) 시스템 별 성능 측정 결과 보고
Unix Project2 <test character device 생성>
UNIT 06 JTAG Debugger 로봇 SW 교육원 조용수.
컴퓨터 구조.
UNIT 07 Memory Map 로봇 SW 교육원 조용수.
Chapter 7. Pentium Processor
07. 디바이스 드라이버의 초기화와 종료 김진홍
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
Ch 13. Windows 관리 기구.
                              데이터베이스 프로그래밍 (소프트웨어 개발 트랙)                               퍼스널 오라클 9i 인스톨.
WinCE Device Driver 실습 #3
WinCE Device Driver 실습 #2
ARM Development Suite v1.2
프로젝트 발표 순서 12/7(수), 팀 별 15분 발표순서 PPT (팀 별 이름, 구현 내용, 결과-그래프 포함) 각 기법당
Chapter 03. 소켓 주소 구조체 다루기.
C#.
Q. 방법#1을 해봐도 실행이 안될 때? Q. 점검 항목이 존재하지 않는다고 할 때?
Cache Manager Yonghyun Kim Microsoft MVP Dev 5 team leader, ESTsoft
UNIT 07 Memory Map 로봇 SW 교육원 조용수.
2장. JSP 프로그래밍을 위한 환경구성 제2장.
Computer System Architecture
컴퓨터의 기초 제 2강 - 변수와 자료형 , 연산자 2006년 3월 27일.
Device Driver 임베디드 시스템 I.
Flash Communication Server
ATmega128의 특징 아이티즌 기술연구소
네트워크 환경 구축과 이미지 전송 호스트/타겟 통신 직렬 통신을 이용한 이미지 전송 수퍼 데몬 BOOTP 환경 구축
Canary value 스택 가드(Stack Guard).
( Windows Service Application Debugging )
OpenCV 설정 2.21 만든이 딩딩.
DK-128 개발환경 설정 아이티즌 기술연구소
DK-128 직렬통신 실습 아이티즌 기술연구소
ARM Development Suite v1.2
발표자 : 이지연 Programming Systems Lab.
구조체(struct)와 공용체(union)
Chapter 11 구조체.
바이트 순서 변환 함수 주소 변환 함수 바이트 조작 함수 원격지 호스트 정보를 얻는 함수
프로그래밍 언어 학습을 위한 가상실습환경 창원대학교 이수현.
동적메모리와 연결 리스트 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
Installation Guide.
06. 디바이스의 등록과 해제 김진홍
ARM Development Suite v1.2
제 1 강 컴퓨터의 구조.
Presentation transcript:

윈도우 커널모드 드라이버 64비트 포팅 월간 마이크로소프트웨어 2005.9 김성현 2006.1.21

목차 64비트 세상 제품 포팅 계획 64비트 CPU 64비트 드라이버 빌드 DDK 예제 포팅 포팅 문제 해결

64비트 세상 INTEL P4 프레스캇 630 – 3GHz System Bus : 800MHz L1 Cache : 16KB L2 Cache : 2MB 64Bit 지원( EM64T ) 하이퍼스레딩 기술 지원

64비트 드라이버 포팅! Why? 64비트 윈도우 정책 WOW64 64비트 드라이버 바이너리 필요!!! 32비트 APP 지원, 32비트 Driver 지원안함 WOW64 32비트 APP 에뮬레이션 레이어 32비트 APP 바이너리 그대로 수행 32비트 Driver 동작 못함 64비트 드라이버 바이너리 필요!!! 32비트, 64비트 One Source, Two Binary

Reserved Address Space NT Executive Win32k.sys Kernel Mode User Mode Reserved Address Space 0x00000000`7FFEFFFF or 0x00000000`FFFEFFFF 64-bit ntdll.dll WoW64.dll WoW64win.dll WoW64cpu.dll 32-bit ntdll.dll 32-bit modules

제품 포팅 계획 32비트 APP 64비트 APP 유저모드 커널모드 64비트 Driver 64비트 Driver 방법1 (제약사항있음) 방법2

FileSystem Redirection 32비트 프로세스로 제품설치시 주의 32비트 APP 접근시 WOW64에서 처리 C:\Program Files => C:\Program Files(x86) C:\windows\system32 => C:\windows\syswow64 Wow64DisableWow64FsRedirection() API 로 제어가능

Registry Redirection 32비트 APP 접근시 WOW64에서 처리 HKLM\Software => HKLM\Software\Wow6432Node HKCR => HKCR\Wow6432Node RegOpenKeyEx(), RegCreateKeyEx() KEY_WOW64_64KEY: 64bit Registry 접근 KEY_WOW64_32KEY: 32bit Registry 접근

64비트 CPU 종류 AMD64 ( AMD ) IA64 ( INTEL ) EM64T ( INTEL ) 32비트 호환 Athlon64, Opteron IA64 ( INTEL ) 진보적인 아키텍쳐(RISC 기반, 32비트 호환?) Itanium, Itanium2 EM64T ( INTEL ) AMD64 Clone? 개발시 AMD64로 취급 ZEON EM64T, Pentium4 with EM64T Q) Dual P4 Hiper Threading EM64T

CPU별 바이너리 종류 지원 대상 CPU 생성할 바이너리 종류 AMD Opteron AMD64 바이너리 AMD Athlon64 Intel Xeon EM64T Intel Pentium 4 with EM64T Intel Itanium processors (including the Itanium2) IA64 바이너리

64비트 드라이버 빌드 DDK 64비트 빌드환경을 제공하는 DDK Windows Server 2003 SP1 DDK http://www.microsoft.com/whdc/devtools/ddk/default.mspx CD 신청 http://www.microsoft.com/whdc/driver/wdf/KMDF_pkg.mspx Download 가능 Thanks OSR!!!

64비트 드라이버 빌드 32비트 드라이버 64비트 드라이버 NT4 빌드? 2K 빌드? XP 빌드? 2K3 빌드! ( XP x64 Edition 커널 )

64비트 드라이버 빌드 DDK 빌드 종류 용도 Windows Server 2003 Checked IA-64 Bit Build Environment IA64용 디버그버전 빌드 Windows Server 2003 Free IA-64 Bit Build Environment 릴리즈버전 빌드 Windows Server 2003 Checked x64 Build Environment AMD64, EM64T Windows Server 2003 Free x64 Build Environment IA64 define : _M_IA64, __IA64__ ; x64 define : _M_AMD64, __AMD64__

64비트 Windows Windows XP x64 Edition Windows XP 64bit Edition Windows Server 2003 x64 Edition Windows Server 2003 for Itanium based system

인라인 어셈블리 OH NO!!! X86 instruction AMD64 instruction IA64 instruction 64비트 컴파일러는 인라인 어셈블리 미지원 원칙 : 1 C-Source Code, 3 Binary

AMD64 Instruction mov [rbp-0x80],rcx mov rdi,[rdi+0x18] movzx ecx,byte ptr [rax+rdi] sub rsp,rcx and rsp,0xfffffffffffffff0 mov rdi,rsp mov rsi,[rbp+0x100] add rsi,0x28 test byte ptr [rbp+0xf0],0x1

IA64 Instruction addl r2=ffffffff`ffe020b8, gp ;; ld8 r2=[r2] nop.i 0 ;; ld8 r3=[r2], 8 ;; ld8 gp=[r2] mov b6=r3, +0 nop.m 0 nop.i 0 br.cond.sptk.few b6

64비트 포팅 가이드라인 _WIN64 define ( _WIN32 ) __AMD64__, __IA64__ 포인터 사용 체크 sizeof(PULONG) != sizeof(ULONG) 포인터 연산 체크 32비트 + 32비트 = 64비트 0xFFFFFFFF != -1

64비트 포팅 가이드라인 ~((UINT64)(PAGE_SIZE-1)) == (UINT64)~(PAGE_SIZE-1) PAGE_SIZE = 0x1000UL // Unsigned Long - 32 bits PAGE_SIZE - 1 = 0x00000fff LHS expression: // Unsigned expansion(UINT64)(PAGE_SIZE -1 ) = 0x0000000000000fff ~((UINT64)(PAGE_SIZE -1 )) = 0xfffffffffffff000 RHS expression: ~(PAGE_SIZE-1) = 0xfffff000 (UINT64)(~(PAGE_SIZE - 1)) = 0x00000000fffff000 ~((UINT64)(PAGE_SIZE-1)) != (UINT64)(~(PAGE_SIZE-1))

드라이버 포팅 예제 NT4 DDK 샘플 64비트 빌드환경 일반샘플처럼 빌드 DDK\src\general\portio 64비트 빌드환경 Windows Server 2003 Checked IA-64(또는 x64) 실행 일반샘플처럼 빌드 생성된 Buildchk_wnet_IA64(또는 AMD64).err 확인

드라이버 포팅 예제

오류내용 1>sys\genport.c(223) : error C4312: 'type cast' : conversion from 'ULONG' to 'PVOID' of greater size 1>sys\genport.c(513) : error C4311: 'type cast' : pointer truncation from 'PVOID' to 'ULONG' 1>sys\genport.c(526) : error C4311: 'type cast' : pointer truncation from 'PVOID' to 'ULONG' 1>sys\genport.c(526) : error C4312: 'type cast' : conversion from 'unsigned long' to 'PUCHAR' of greater size 1>sys\genport.c(530) : error C4311: 'type cast' : pointer truncation from 'PVOID' to 'ULONG' 1>sys\genport.c(530) : error C4312: 'type cast' : conversion from 'unsigned long' to 'PUSHORT' of greater size 1>sys\genport.c(534) : error C4311: 'type cast' : pointer truncation from 'PVOID' to 'ULONG'

포인터의 타입캐스팅 데이터 타입의 크기에 대한 문제 포인터와 ULONG을 구분하지 않고 작성된 코드에 대한 문제 32비트 환경 포인터 크기: 32비트 32비트 환경 ULONG 크기: 32비트 64비트 환경 포인터 크기: 64비트 64비트 환경 ULONG 크기: 32비트 포인터와 ULONG을 구분하지 않고 작성된 코드에 대한 문제

포인터의 타입캐스팅 1>sys\genport.c(513) : error C4311: 'type cast' : pointer truncation from 'PVOID' to 'ULONG‘ 511 : if (nPort >= pLDI->PortCount || 512 : (nPort + DataBufferSize) > pLDI->PortCount || 513 : (((ULONG)pLDI->PortBase + nPort) & (DataBufferSize - 1)) != 0) pLDI->PortBase는 PVOID, nPort 는 ULONG 타입캐스팅이 에러?

포인터의 타입캐스팅 해결방법 1 ULONG_PTR ULONG 형 포인터? X 32비트 빌드시: 32비트 크기의 정수형 513 : (((ULONG_PTR)pLDI->PortBase + nPort) & (DataBufferSize - 1)) != 0) ULONG_PTR ULONG 형 포인터? X 32비트 빌드시: 32비트 크기의 정수형 64비트 빌드시: 64비트 크기의 정수형

포인터의 타입캐스팅 해결방법 2 PtrToUlong() 매크로 513 : ((PtrToUlong(pLDI->PortBase) + nPort) & (DataBufferSize - 1)) != 0) PtrToUlong() 매크로 #define PtrToUlong( p ) ((ULONG)(ULONG_PTR) (p) ) 주의) pLDI->PortBase가 32비트로 잘림

포인터의 타입캐스팅 1>sys\genport.c(526) : error C4311: 'type cast' : pointer truncation from 'PVOID' to 'ULONG' 1>sys\genport.c(526) : error C4312: 'type cast' : conversion from 'unsigned long' to 'PUCHAR' of greater size 524 : case IOCTL_GPD_READ_PORT_UCHAR: 525: *(PUCHAR)pIOBuffer = READ_PORT_UCHAR( 526: (PUCHAR)((ULONG)pLDI->PortBase + nPort) ); 527: break; 한줄에 2가지 오류

포인터의 타입캐스팅 방법 1 방법 2 방법 2+ 신중히 결정할 것 주의) 반복되는 오류처리 (PUCHAR)((ULONG_PTR)pLDI->PortBase + nPort)); 방법 2 (PUCHAR)PtrToUlong(pLDI->PortBase) + nPort); 방법 2+ (PUCHAR)UlongToPtr(PtrToUlong(pLDI->PortBase) + nPort)); 신중히 결정할 것 주의) 반복되는 오류처리

타입캐스팅을 넘어서 1>sys\genport.c(223) : error C4312: 'type cast' : conversion from 'ULONG' to 'PVOID' of greater size 223 : pLocalInfo->PortBase = (PVOID)MappedAddress.LowPart; MappedAddress.LowPart 는 ULONG 타입캐스팅으로 해결? 아니면?

타입캐스팅을 넘어서 해결방법 1 223 : pLocalInfo->PortBase = UlongToPtr( MappedAddress.LowPart ); 해결방법 2 223 : pLocalInfo->PortBase = (PVOID)(ULONG_PTR)MappedAddress.LowPart;

타입캐스팅을 넘어서 해결방법 3 MappedAddress의 타입 데이터구조를 생각하자 LowPart? HighPart? PHYSICAL_ADDRESS MappedAddress; typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS;

타입캐스팅을 넘어서 typedef union _LARGE_INTEGER { struct { ULONG LowPart; LONG HighPart; }; } u; LONGLONG QuadPart; // 64비트!!! } LARGE_INTEGER;

타입캐스팅을 넘어서 해결방법 3 198: HalTranslateBusAddress( Isa, 199: 0, 223 : pLocalInfo->PortBase = (PVOID)MappedAddress.QuadPart; 198: HalTranslateBusAddress( Isa, 199: 0, 200: PortAddress, 201: &MemType, 202: &MappedAddress );

응용 프로그램과 드라이버가 공유하는 구조체 기존 32비트 응용프로그램이 사용하던 구조체를 새로 작성되는 64비트 드라이버에 전달해야 할 때 32비트 환경과 64비트 환경에서 데이터 크기가 달라지는 타입에 대한 문제

응용 프로그램과 드라이버가 공유하는 구조체 응용 프로그램 코드 예제 드라이버 코드 예제 GENPORT_WRITE_INPUT InputBuffer sscanf(argv[2],"%x",&InputBuffer.PortNumber); InputBuffer.LongData = (ULONG)DataValue; 드라이버 코드 예제 GENPORT_WRITE_INPUT *pInputBuffer nPortNum = pInputBuffer->PortNumber; nLongData = pInputBuffer->LongData;

응용 프로그램과 드라이버가 공유하는 구조체 Gpioctl.h typedef struct _GENPORT_WRITE_INPUT { ULONG PortNumber; // Port # to write to union { // Data to be output to port ULONG LongData; USHORT ShortData; UCHAR CharData; }; } GENPORT_WRITE_INPUT;

응용 프로그램과 드라이버가 공유하는 구조체 32비트 APP + 64비트 DRV 32 비트 gpdwrite.exe 64 비트 genport.sys 32 비트 gpdwrite.exe GENPORT_WRITE_INPUT (ULONG 4 바이트, union 4 바이트)

공유 구조체 문제 32비트, 64비트에서 크기가 다른 데이터가 존재하는 경우 typedef struct _GENPORT_WRITE_INPUT { PVOID PortNumber; union { ULONG LongData; USHORT ShortData; UCHAR CharData; }; } GENPORT_WRITE_INPUT;

공유 구조체 문제 32비트 APP + 64비트 DRV 32 비트 gpdwrite.exe GENPORT_WRITE_INPUT 64 비트 genport.sys 32 비트 gpdwrite.exe GENPORT_WRITE_INPUT (PVOID 4 바이트, union 4 바이트) (PVOID 8 바이트,

공유 구조체 문제 해결 64비트 드라이버가 사용하는 32비트용 구조체 정의 typedef struct _GENPORT_WRITE_INPUT_32 { ULONG PortNumber; union { ULONG LongData; USHORT ShortData; UCHAR CharData; }; } GENPORT_WRITE_INPUT;

공유 구조체 문제 해결 32비트 APP + 64비트 DRV 64 비트 genport.sys 32 비트 gpdwrite.exe GENPORT_WRITE_INPUT (PVOID 4 바이트, union 4 바이트) GENPORT_WRITE_INPUT_32 (ULONG 4 바이트,

IoIs32bitProcess() 시나리오 64비트 드라이버의 운명은? 32비트 기존 응용프로그램 사용 64비트 드라이버 출시 후… 64비트 응용프로그램 포팅 완료 64비트 드라이버의 운명은? 32 APP, 64 APP 모두 지원 32 APP, 64 APP 구분 필요

IoIs32bitProcess() 64비트 APP + 64비트 DRV 64 비트 gpdwrite.exe GENPORT_WRITE_INPUT (PVOID 8 바이트, union 4 바이트) 64 비트 genport.sys GENPORT_WRITE_INPUT (PVOID 8 바이트, union 4 바이트)

IoIs32bitProcess() GENPORT_WRITE_INPUT *pInputBuffer If (IoIs32bitProcess( Irp ) == TRUE) pInputBuffer32 = (GENPORT_WRITE_INPUT_32*) pIrp->AssociatedIrp.SystemBuffer; else pInputBuffer = (GENPORT_WRITE_INPUT*) pIrp->AssociatedIrp.SystemBuffer; switch (IoctlCode) { case IOCTL_GPD_WRITE_PORT_ULONG: nPortNum = pInputBuffer32->PortNumber; nLongData = pInputBuffer32->LongData; } Else // 64 bit nPortNum = pInputBuffer->PortNumber; nLongData = pInputBuffer->LongData;

IoIs32bitProcess() IOCTL Code 사용하는 방법 현재 64비트 Device Type (16) Access (2) Custom(1) Function (11) Method (2) Device Type (16) Access (2) Custom(1) 64-Bit (1) Function (10) Method (2)

Quiz #pragma pack(1) typedef struct _PACK1_DATA { ULONG ul1; UCHAR uc1; } PACK1_DATA; #pragma pack() #pragma pack(8) typedef struct _PACK8_DATA UCHAR uc8; PACK1_DATA p1d; ULONG ul8; } PACK8_DATA;

Quiz 32비트 환경에서 메모리 구성은? 1 2 3 uc8 ul1 uc1 ul8 uc8 ul1 uc1 ul8 uc8 ul1 padding ul1 uc1 padding ul8 uc8 ul1 uc1 padding ul8 uc8 padding ul1 uc1 ul8

Data Misalignment 문제 IA64에서 발생하는 문제 메모리 주소 경계에 맞지 않는 주소를 액세스할 경우 APP => 비정상종료 DRV => 블루스크린 Bug Check 0x1E: KMODE_EXCEPTION_NOT_HANDLED Parameter 1: 0x80000002 STATUS_DATATYPE_MISALIGNMENT

Data Misalignment 문제 #pragma pack(1) typedef struct _GENPORT_WRITE_INPUT { BOOLEAN bTest; PVOID PortNumber; // Port # to write to union { // Data to be output to port ULONG LongData; USHORT ShortData; UCHAR CharData; }; } GENPORT_WRITE_INPUT; #pragma pack()

Data Misalignment 문제 1바이트 정렬된 구조체의 메모리구조 bTest GENPORT_WRITE_INPUT 0 1 2 3 4 5 6 7 8 9 10 11 12 PortNumber LongData

Data Misalignment 문제 해결 1. 예외 핸들링 2. 구조체를 정렬된 형태로 수정 3. 컴파일러에게 도움 요청

Data Misalignment 문제 해결 구조체 선언시 #pragma pack(1) 제거 8바이트 정렬된 구조체의 메모리구조 GENPORT_WRITE_INPUT 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 bTest Padding PortNumber LongData

Data Misalignment 문제 해결 메모리 공간 절약 배치 typedef struct _GENPORT_WRITE_INPUT { PVOID PortNumber; // Port # to write to union { // Data to be output to port ULONG LongData; USHORT ShortData; UCHAR CharData; }; BOOLEAN bTest; } GENPORT_WRITE_INPUT;

Data Misalignment 문제 해결 8바이트 정렬하고 bTest를 맨뒤로… bTest GENPORT_WRITE_INPUT 0 1 2 3 4 5 6 7 8 9 10 11 12 PortNumber LongData

Data Misalignment 문제 해결 컴파일러에게 도움 요청 죽어도 #pragma pack(1) 을 써야할 경우 32비트 응용 프로그램의 구조체를 수정하지 못할 경우 UNALIGNED 매크로 문제가 있는 코드임을 컴파일러에게 알림 1바이트씩 읽어서 조합해 주는 코드 생성 주의) 성능 저하의 우려가 있음

Data Misalignment 문제 해결 데이터 미정렬 예외(data misalignment exception)가 발생하는 코드 pInputBuffer->PortNumber = p; 데이터 미정렬 예외(data misalignment exception)가 발생하지 않는 코드 *(UNALIGNED PVOID) &pInputBuffer->PortNumber = p;

참고자료 DDK Help: 64-Bit Issues MS 사이트 64-bit Platform 드라이버 포팅 기본 가이드 http://www.microsoft.com/whdc/system/platform/64bit/default.mspx 64비트 개발관련 수많은 문서

Q & A