Title: Drivers For 64Bit Windows Nar Ganapathy Software Design Engineer Windows NT Base Systems Microsoft C
1Drivers For 64-Bit Windows Nar
GanapathySoftware Design EngineerWindows NT
Base SystemsMicrosoft Corporation
2(No Transcript)
3Agenda
- What is 64-bit Windows
- Programming model
- Porting guidelines
- Programming issues
464-Bit Windows 2000 Goals
- Porting from Win32 to Win64? should be simple
- A single source code base for Win32 and Win64
- Enable existing applications to scale to
enterprise capacities - Enable new designs that use huge address space
and memory - Support existing 32-bit applications
- 32-bit device drivers not supported
5What Is 64-Bit Version Of Windows 2000?
- 64-Bit Windows is an evolution of the Windows
programming model and APIs - LLP64 model
- Pointers are expanded to 64 bits
- Memory allocation sizes are 64 bits
- Longs and ints are 32 bits
6Win64 Programming Model
- Uses the same Win32 DDIs/APIs
- Adds new explicitly sized types
- Adds new integral types that match the precision
of a pointer - Almost all Win32 32-bit data types remain 32-bits
- E.g., size of ULONG is still 32 bits under Win64
- Pointers are 64-bits
7Win64 Programming Model
- Items expanded to 64 bits
- Length for most memory allocations
- CPU mask
- Unchanged
- Length for I/O operations
- Unicode string lengths
8Win64 Data Types
9Win64 Data Types Continued
10Win64 Porting Guidelines
- Use Win64 safe data types
- Examine all pointer usage, especially pointer
arithmetic - Two major porting topics
- Driver specific issues (e.g., IOCTLs, DMA)
- Programming issues
11Memory Management (IA64)
- User addresses range from 0x10000
0x000006FBFFFEFFFF - One terabyte system cache
- Sixteen gigabyte HyperSpace
- 128 gigabyte paged pool
- 128 gigabyte System address space for kernel
threads, etc. - 128 gigabyte non-paged pool
- Physical memory addresses are 64 bits
12WOW64
- Runs Windows NT x86 binaries
- No support for mixing of x86 and IA-64 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 release shares
13Driver Specific Issues
- Drivers need to support Plug and Play and Power
Management - I/O request length is limited to 32 bits
- 32-bit devices will be double buffered for DMA
transfers - Some drivers will need to support 32- and 64-bit
versions of IOCTL command
14Support 32-Bit IOCTLS
- 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 issuers bit width
15Supporting 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
1632 And 64-Bit IOCTL Example
- IOCTL structure in header file
typedef struct _IOCTL_PARAMETERS PVOID
Addr SIZE_T Length HANDLE Handle
IOCTL_PARAMETERS, PIOCTL_PARAMETERS
1732 And 64-Bit IOCTL Example
// // This structure is defined inside the driver
source code // typedef struct _IOCTL_PARAMETERS_32
VOIDPOINTER_32 Addr INT32
Length VOIDPOINTER_32 Handle
IOCTL_PARAMETERS_32, PIOCTL_PARAMETERS_32
1832 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-gtAssociatedIrp.SystemBuffer)
if(irpSp-gtParameters.DeviceIoControl.InputBufferLe
ngth lt
sizeof(PIOCTL_PARAMETERS_32))
status STATUS_INVALID_PARAMETER
else
LocalParam.Addr params32-gtAddr
LocalParam.Handle params32-gtHandle
LocalParam.Length
params32-gtLength / Handle the ioctl here
/ status STATUS_SUCCESS
Irp-gtIoStatus.Information
sizeof(IOCTL_PARAMETERS)
1932 And 64-Bit IOCTL Example
else / 64bit process IOCTL / params
(PIOCTL_PARAMETERS) (Irp-gtAssociatedIrp
.SystemBuffer) if (irpSp-gtParameters.DeviceIoCo
ntrol.InputBufferLength
lt sizeof(IOCTL_PARAMETERS))
status STATUS_INVALID_PARAMETER
else
RtlCopyMemory(LocalParam, params,
sizeof(IOCTL_PARAMETERS))
/ Handle the ioctl here / status
STATUS_SUCCESS Irp-gtIoStatus.Information
sizeof(IOCTL_PARAMETERS) break
20Use New IOCTL Code
- Use bit in function field to indicate 64-bit
IOCTL - Current IOCTL codes have four fields
- New IOCTL code has one extra bit for 64 bit
21DMA APIs
- Drivers should use PHYSICAL_ADDRESS typedef to
access physical addresses (64 bits long) - Driver must treat all 64 bits as a Valid Physical
Address, do not ignore top 32 bits - Drivers must use the Windows DMA APIs
- IoAllocateAdapter, IoAllocateAdapterChannel,IoMapT
ransfer,etc. - Use new scatter/gather DMA APIs
- Devices with 64-bit addressing capability will
significantly improve performance
22Programming Issues
- Polymorphic Data usage
- Miscellaneous cleanup
- Alignment issues
23Polymorphic Data Usage
- Dont cast pointer to int, long, ULONG, DWORD
- Use UINT_PTR and INT_PTR
ImageBase (PVOID) ((ULONG)ImageBase 1)
Should be re-written as
ImageBase (PVOID) ((ULONG_PTR)ImageBase
1)
24Polymorphic Data Usage
- Use PtrToUlong and PtrToLong to truncate pointers
- Never cast a int or ULONG that stores a truncated
pointer back to a pointer - Be careful when computing buffer sizes Sizes
may exceed capacity of ULONG
25Polymorhpic Data Usage
- Be careful when calling functions that have
pointer OUT parameters
void GetBufferAddress(OUT PULONG
ptr) ptr0x1000100010001000 void
foo() ULONG bufAddress // // this call
causes memory corruption //
GetBufferAddress((PULONG )bufAddress)
26Miscellaneous 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)
27Miscellaneous Cleanup
- Use I to print pointers in debug statements
- Addresses gt 0x80000000 are not necessarily
kernel addresses
28Alignment
- Misaligned memory references will raise an
exception on Win64
pragma pack (1) / also set by /Zp switch
/ struct AlignSample ULONG size void ptr
void foo(void p) struct AlignSample
s s.ptr p // will cause alignment
fault ...
29Alignment
- Use UNALIGNED macro to fix
- Better solution is to put 64-bit values and
pointers at the beginning of the structure
void foo(void p) struct AlignSample s
(UNALIGNED void )s.ptr p
30Alignment
- Be cautious of any structure packing directives
- Be especially cautious of different PACK levels
used in the same header - RtlCopyMemory and memcpy will not fault
31More Programming Issues
- Carefully examine
- Explicit and implicit unions with pointers
- Data structures stored on disk or exchanged with
32-bit processes - Security descriptors
- Code which deals with memory region sizes
- len ptr2 ptr1
- len could be greater than 232
32Miscellaneous Programming Issues
- Executive handles can be truncated to 32 bit
- Piecemeal size allocations
struct foo DWORD NumberOfPointers PVOID
Pointers1 xx Wrong malloc(sizeof(DWORD)100
sizeof(PVOID)) Correct malloc(FIELD_OFFSET(str
uct foo,Pointers) 100sizeof(PVOID))
33MiscellaneousProgramming Issues
- Be careful when using hexadecimal constants and
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
))
34Miscellaneous Programming Issues
- Be careful when using unsigned numbers as
subscripts - DWORD index 0
- CHAR p
- If (pindex 1 0) causes access violation
on Win64! - On 32-bit machines
- pindex-1 p0xffffffff p-1
- On 64-bit machines
- pindex-1 p0x00000000ffffffff ! p-1
35Call To Action
- Develop Windows 2000 ready drivers by supporting
Plug and Play and Power Management - Start coding using Win64 safe programming
practices now! - Use the 64-bit compiler to find problem areas
- Make your devices address 64 bits of physical
memory
36Additional Information
- Read Getting Ready for 64-bit Windows porting
guide on Windows 2000 SDK - Other information available at http//www.microsof
t.com/windows2000/guide/platform/strategic/64bit.a
sp
37(No Transcript)