Presentation is loading. Please wait.

Presentation is loading. Please wait.

Moving Drivers To 64-Bit Nar Ganapathy Architect Windows Device Experience Group Microsoft Corporation.

Similar presentations


Presentation on theme: "Moving Drivers To 64-Bit Nar Ganapathy Architect Windows Device Experience Group Microsoft Corporation."— Presentation transcript:

1 Moving Drivers To 64-Bit Nar Ganapathy Architect Windows Device Experience Group Microsoft Corporation

2 Agenda 64 bit Windows goals Programming model Porting guidelines ToolsSummaryResources Call to action

3 64-Bit Windows Goals Supporting both Win32® 32-bit and 64-bit should be simple A single source code base for 32-bit and 64-bit platforms Enable existing applications to scale to enterprise capacities Enable new designs that use huge address space and memory Support existing 32-bit applications

4 What Is Windows 64-Bit Edition? 64-bit Windows is enabled by an evolution of the Windows programming model and the Win32 API LLP64 model Pointers are expanded to 64 bits Memory allocation sizes are 64 bits Longs and ints default to 32 bits Specific types for 64-bit integers

5 Why port drivers to 64-bit Windows ? Increase device coverage for 64-bit windows No support for 32-bit drivers Kernel-mode drivers running in same address space as 64-bit OS Scaling to large systems Can make use of larger address spaces for paged/non-paged pool and system cache

6 64-Bit Programming Model Uses the same Win32 DDIs/APIs Adds new explicitly sized types Adds new integral types that match the precision of a pointer Pointer Precision Type Fixed Width Type Most Win32 32-bit data types remain 32-bits E.g., size of ULONG is 32 bits Pointers are 64 bits

7 64-Bit Programming Model Example of items expanded to 64 bits Length for most memory allocations CPU mask Unchanged Length for I/O operations Unicode string lengths

8 Fixed-Width Data Types Type name What it is LONG32, INT32 32-bit signed LONG64, INT64 64-bit signed ULONG32,UINT32, DWORD32 32-bit unsigned ULONG64,UINT64, DWORD64 64-bit unsigned

9 Pointer-Precision Data Types Type name What it is INT_PTR,LONG_PTR Signed Int, Pointer precision UINT_PTR,ULONG_PTR,DWORD_PTR Unsigned Int, Pointer precision SIZE_T Unsigned count, Pointer precision SSIZE_T Signed count, Pointer precision

10 IA-64 Memory Layout User addresses range from 0x10000 – 0x000006FBFFFEFFFF One terabyte system cache 16 gigabyte HyperSpace 128 gigabyte paged pool 128 gigabyte System address space for kernel threads, etc. 8K page size 128 gigabyte non-paged pool Physical memory addresses are 64 bits

11 x64 Memory Layout User addresses range from 0x10000 – 0x000007FFFFFEFFFF One terabyte system cache 512 gigabyte HyperSpace 128 gigabyte paged pool 128 gigabyte System address space for kernel threads, etc. 4K page size 128 gigabyte non-paged pool Physical memory addresses are 64 bits

12 Coding Guidelines Use Windows 64-bit and 32-bit safe data types Examine all pointer usage, especially pointer arithmetic Remove inline assembly code (use intrinsics or native assembly code) Use #if defined (__AMD64__) for X64-specific code No __X64__ definition Use #if defined(__IA64__) for IA64-specific code Build environment for x64 is AMD64

13 Porting issues for Drivers Driver support for 32-bit and 64-bit versions of IOCTL commands DMA support For hardware that can address only 32 bits of physical address Drivers need to be WDM-compliant Support Plug and Play and Power Management Legacy (Windows NT4) APIs not allowed Programming issues User-mode drivers need to be 64 bit also Print, Scan, Camera Other miscellaneous issues

14 WOW64 Windows on Windows Runs Windows NT ® x86 binaries No support for mixing of 32-bit and 64-bit code within a process User/kernel transitions are thunked to account for structure differences and transition between instruction sets Only a few DLLs are thunked: ntdll.dll, user.dll, gdi.dll plus a set of LPC calls The rest of the DLLs are stock x86 binaries copied from the 32-bit release shares

15 Support 32-Bit IOCTL IOCTL structures that contain pointer- dependent types have different sizes in 64-bit and 32-bit applications Driver has to distinguish between IOCTLs issued from 32-bit or 64-bit threads Driver validates the input or output buffer lengths based on the issuer’s bit width

16 Supporting 32-Bit IOCTL Three possible solutions Avoid having pointer types in IOCTL structures Use the API IoIs32bitProcess() Use a new bit in the Function code field of the IOCTL code for 64-bit callers

17 32-Bit and 64-Bit IOCTL Example IOCTL structure in header file typedef struct _IOCTL_PARAMETERS { PVOID Addr; PVOID Addr; SIZE_T Length; SIZE_T Length; HANDLE Handle; HANDLE Handle; } IOCTL_PARAMETERS, *PIOCTL_PARAMETERS;

18 32-Bit and 64-Bit IOCTL Example 32-bit IOCTL structure // // This structure is defined // inside the driver source code // typedef struct _IOCTL_PARAMETERS_32 { VOID*POINTER_32 Addr; VOID*POINTER_32 Addr; INT32 Length; INT32 Length; VOID*POINTER_32 Handle; VOID*POINTER_32 Handle; } IOCTL_PARAMETERS_32, *PIOCTL_PARAMETERS_32;

19 32-Bit and 64-Bit IOCTL Example #ifdef _WIN64 case IOCTL_REGISTER: if (IoIs32bitProcess(Irp)) { /* If this is a 32 bit process */ params32 = (PIOCTL_PARAMETERS_32)(Irp>AssociatedIrp.SystemBuffer); if(irpSp->Parameters.DeviceIoControl.InputBufferLength Addr; LocalParam.Handle = params32->Handle; LocalParam.Length = params32->Length; if(irpSp->Parameters.DeviceIoControl.InputBufferLength Addr; LocalParam.Handle = params32->Handle; LocalParam.Length = params32->Length; /* Handle the ioctl here */ /* Handle the ioctl here */ status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof(IOCTL_PARAMETERS); } } else { /* 64bit process IOCTL */ -> (See Next Slide) ->

20 32-Bit and 64-Bit IOCTL Example <- (From Last Slide) <- } else { /* 64bit process IOCTL */ params = (PIOCTL_PARAMETERS) (Irp->AssociatedIrp.SystemBuffer); params = (PIOCTL_PARAMETERS) (Irp->AssociatedIrp.SystemBuffer); if (irpSp->Parameters.DeviceIoControl.InputBufferLength Parameters.DeviceIoControl.InputBufferLength < sizeof(IOCTL_PARAMETERS)) { status = STATUS_INVALID_PARAMETER; } else { RtlCopyMemory(&LocalParam, params, sizeof(IOCTL_PARAMETERS)); } else { RtlCopyMemory(&LocalParam, params, sizeof(IOCTL_PARAMETERS)); /* Handle the ioctl here */ status = STATUS_SUCCESS; } Irp->IoStatus.Information = sizeof(IOCTL_PARAMETERS); } break; /* Handle the ioctl here */ status = STATUS_SUCCESS; } Irp->IoStatus.Information = sizeof(IOCTL_PARAMETERS); } break;

21 Use New IOCTL Code Use bit in function field to indicate 64-bit IOCTL Current IOCTL codes have five fields New IOCTL code has an extra bit for 64-bit 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)

22 DMA Support Drivers should use PHYSICAL_ADDRESS typedef to access physical addresses (64 bits long) Driver must treat all 64 bits as a valid physical address and not ignore top 32 bits Drivers must use the Windows DMA APIs IoGetDmaAdapter(), AllocateAdapterChannel(), MapTransfer(), etc. Use new scatter/gather DMA APIs Devices with 64-bit addressing capability will significantly improve performance

23 64-Bit INF requirement Goal is to prevent installation of incorrect driver binaries Customers do not understand the difference in platforms Can use TargetOsVersion Introduced in Windows XP Not widely used With Server 2003 SP1 Manufacturer & Models Sections MUST be decorated for 64-bit platforms [Manufacturer] %mycompany% = MyCompanyModels, NTamd64 [MyCompanyModels.NTamd64] %MyDev% = mydevInstall, mydevHwid Legacy IA64 INFs will continue to work More information at http://www.microsoft.com/whdc/driver/install/64INF_reqs.mspx

24 Make your driver a WDM driver Support Plug and Play and power management Most modern buses and devices support Plug and Play and power management Key to supporting many desktop and mobile scenarios Move from driver-centric to device-centric model Handle PnP/PM IRPs or follow miniport guidelines More information in the DDK and at http://www.microsoft.com/whdc

25 Misc. Driver-Specific Issues BIOS callbacks are not allowed on X64 IA-64 Systems must support ACPI 2.0 64-bit Tables. More details at http://www.microsoft.com/whdc/system/pla tform/64bit/IA64_ACPI.mspx http://www.microsoft.com/whdc/system/pla tform/64bit/IA64_ACPI.mspx http://www.microsoft.com/whdc/system/pla tform/64bit/IA64_ACPI.mspx GPT disks are supported by 64-bit Windows I/O request length is limited to 32 bits Modifying IDT, GDT, System Service Tables, process and thread structures is illegal Enforced on X64 platforms Results in a bugcheck

26 64-Bit Miniport Guidelines Follow miniport-specific guidelines given in the DDK Watch out for change in PAGE_SIZE (8K on IA64, 4K on x64) IOCTL, PnP and DMA issues non-existent for most miniports Pointers, polymorphic usage and alignment issues apply to miniports

27 Pointer Size Related Issues Common across applications and drivers Application porting guidelines applicable here They are Polymorphic data usage (pointer size related) Alignment issues Constant and Macros arithmetic

28 Polymorphic Data Usage … Don’t cast a pointer to any of: int, long, ULONG, DWORD Use UINT_PTR and INT_PTR Use UINT_PTR and INT_PTR ImageBase = (PVOID) ((ULONG)ImageBase | 1); ImageBase = (PVOID) ((ULONG_PTR)ImageBase | 1); Should be re-written as:

29 …Polymorphic Data Usage Use PtrToUlong() and PtrToLong() to truncate pointers Never cast an int or a ULONG that stores a truncated pointer back into a pointer Be careful when computing buffer sizes; sizes may exceed capacity of ULONG

30 … Polymorphic Data Usage Be careful when calling functions that have pointer OUT parameters void GetBufferAddress(OUT PULONG *ptr); {*ptr=0x1000100010001000;} void foo() { ULONG bufAddress; ULONG bufAddress; // // // this call causes memory corruption // this call causes memory corruption // // GetBufferAddress((PULONG*)&bufAddress); GetBufferAddress((PULONG*)&bufAddress);}

31 Alignment (1 of 4) IA-64 requires natural alignment for memory references (e.g. 32-bit accesses at a 4-byte boundary) Misaligned memory references will raise an exception on IA-64 and bugcheck the system x64 is more forgiving but alignment required to get better performance Use UNALIGNED macro to fix alignment problems

32 Alignment (2 Of 4) #pragma pack (1) /* also set by /Zp switch */ struct AlignSample { ULONG size; void *ptr; }; struct AlignSample s; void foo(void *p) { *p = p;// causes alignment fault...}foo((PVOID)&s.ptr);

33 Alignment (3 Of 4) Use UNALIGNED macro to fix Better solution: Put 64-bit values and pointers at start of structures void foo(void *p) { struct AlignSample s; *(UNALIGNED void *)&s.ptr = p; *(UNALIGNED void *)&s.ptr = p;}

34 Alignment (4 Of 4) Be aware of alignment issues around any structure-packing directives Be especially cautious of different PACK levels used in the same header Note: RtlCopyMemory() and memcpy() will not fault

35 More Coding Issues Carefully examine: Explicit and implicit unions with pointers Data structures stored on disk or exchanged with 32-bit processes Security descriptors Code that deals with memory region sizes len = ptr2 – ptr1 len could be greater than 2^32

36 Misc. Coding Issues Executive handles can be truncated to 32-bit Piecemeal size allocations: struct foo { DWORD NumberOfPointers; PVOID Pointers[1]; } xx; Wrong:malloc(sizeof(DWORD)+100*sizeof(PVOID));Correct: malloc(FIELD_OFFSET(struct foo,Pointers) +100*sizeof(PVOID));

37 More Misc. Coding Issues Use care with hex constants, unsigned values Following assertion not true on 64-bit systems ~((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 Hence ~((UINT64)(PAGE_SIZE-1))!= (UINT64)(~(PAGE_SIZE-1))

38 Even More Coding Issues Care with unsigned numbers as subscripts: DWORD index = 0; CHAR *p; If (p[index – 1] == ‘0’) causes an access violation on IA-64! On 32-bit machines: p[index-1] == p[0xffffffff] == p[-1] On 64-bit machines: p[index-1] == p[0x00000000ffffffff] != p[-1]

39 Miscellaneous Cleanup -1 != 0xFFFFFFFF 0xFFFFFFFF != invalid handle DWORD is always 32 bits Look for DWORD variables used to store pointers or handles Cast pointers to PCHAR for pointer arithmetic ptr = (PVOID)((PCHAR)ptr + pageSize);

40 Miscellaneous Cleanup (Contd.) Use %I to print pointers in debug statements Addresses >= 0x80000000 are not necessarily kernel addresses

41 Tools for developing drivers 64-bit tools and development process very similar to 32 bit Debugger Cross compilers in the DDK Checked builds Driver Verifier

42 Summary Driver Model and tools remain the same for 32 bit and 64 bit Application porting guidelines apply to drivers Driver specific issues relate to IOCTLs, DMA and legacy DDIs

43 Additional Information Read 64-bit guide in the DDK http://msdn.microsoft.com/library/default.asp? url=/library/en- us/kmarch/hh/kmarch/Other_f910e5d8-a732- 4faa-a8d2-d4de021dc78d.xml.asp http://msdn.microsoft.com/library/default.asp? url=/library/en- us/kmarch/hh/kmarch/Other_f910e5d8-a732- 4faa-a8d2-d4de021dc78d.xml.asp More HW related information available at http://www.microsoft.com/whdc/system/platfor m/64bit/default.mspx http://www.microsoft.com/whdc/system/platfor m/64bit/default.mspx

44 Call To Action Develop WDM drivers that: Support Plug and Play Support Power Management Start coding with 64-bit safe programming practices Use 64-bit compiler to find problem areas Make your devices address 64 bits of physical memory


Download ppt "Moving Drivers To 64-Bit Nar Ganapathy Architect Windows Device Experience Group Microsoft Corporation."

Similar presentations


Ads by Google