What is Memory Descriptor Lists?

A memory descriptor list (MDL) describes a list of pages in physical memory. Internally, the Windows kernel uses MDLs in numerous ways. For example, when the I/O manager sets up a direct I/O request to send to a driver, it creates an MDL to describe the I/O buffer. The driver receives a pointer to the MDL in the request at Irp->MdlAddress.

When the driver receives the request, the pages described by the MDL have already been locked into memory by the creator of the MDL. To use virtual addresses to access the buffer described by the MDL, the driver calls MmGetSystemAddressForMdlSafe to map the buffer into system space. This function returns a valid system-space virtual address that the driver can use to access the buffer.
·         The driver receives an I/O request for neither buffered nor direct (METHOD_NEITHER) I/O.
·         The driver initiates an I/O request to send to another driver.
·         The driver splits a large I/O buffer into two or more smaller buffers. 
·         The driver allocates physical memory from a specific physical address range.

When a driver receives a request for METHOD_NEITHER I/O, a pointer to a buffer is part of the request. If the originator of the I/O request is another kernel-mode component, the buffer can be in system space. More often, however, the originator of the request is a user-mode process, so the buffer is in user space. To read and write to this user-space buffer, the driver must create an MDL that describes these pages and must ensure that they remain accessible until the driver has completed the I/O request. Creating the MDL locks the pages into memory so that any subsequent access is guaranteed to be protected. If the driver must use virtual addresses to access the pages described by the MDL, it must map those pages into the system address space using MmGetSystemAddressForMdlSafe. This function returns a valid system-space virtual address with which the driver can safely access the buffer.  

When a driver initiates an I/O request, it allocates an MDL to describe the buffer in the I/O request. For example, a driver might send a device I/O control request (IRP_MJ_INTERNAL_DEVICE_CONTROL) to a lower driver in its stack to request some kind of intervention with the hardware. The driver would call IoAllocateMdl to create an MDL and later use a different system function to fill in the MDL, depending on the type of request. If the request specifies direct I/O, the lower driver would receive a pointer to the MDL in the request at Irp‑>MdlAddress.

To split a large I/O buffer into smaller buffers, a driver might also use an MDL. Typically, splitting a buffer in this way is required only during direct I/O operations, if the supplied buffer is too large for the device or if the driver or device can operate more efficiently with several smaller buffers. To split a buffer, the driver calls IoAllocateMdl to create the new MDL, and then calls IoBuildPartialMdl to map a subset of the range described by the original MDL into the new one.   

A driver that allocates physical memory from a specific range of addresses must also create an MDL to describe the allocated memory. In this case, the driver calls MmAllocatePagesForMdl (which allocates the memory), creates the MDL, and locks the pages. If the driver requires access to the pages through virtual addresses, the driver also calls MmGetSystemAddressForMdlSafe to map the pages into virtual memory and return a virtual address for the driver’s use. 
Table 2. Summary of MDL Routines
Name
Description
MmAllocateMappingAddress
Reserves a range of virtual addresses for mapping, but does not actually map them to physical memory.
To map the virtual addresses in the reserved range to physical addresses, the driver later calls IoAllocateMdl, MmProbeAndLockPages, and MmMapLockedPagesWithReservedMapping. This technique is less efficient than calling MmGetSystemAddressForMdlSafe or MmMapLockedPagesXxx, but is useful because it allows driver execution to continue in situations when calling these latter functions fails.  
IoAllocateMdl
Allocates an MDL for a buffer, given the starting virtual address of the buffer and its length.
This routine does not associate the physical pages in the buffer with the allocated MDL. To do so, the driver must call MmBuildMdlForNonPagedPool, IoBuildPartialMdl, or MmProbeAndLockPages
MmProbeAndLockPages
Confirms that the pages described by an MDL permit the requested type of access and, if so, locks those pages into memory. 
MmBuildMdlForNonPagedPool
Fills in an MDL to describe a buffer that is allocated in system-space memory from the nonpaged pool. The MDL must have been allocated by IoAllocateMdl.
A driver can also use this function on I/O space, typically by mapping the space with MmMapIoSpace and then passing the returned virtual address to MmBuildMdlForNonPagedPool.
MmAllocatePagesForMdl
Allocates nonpaged, noncontiguous pages from physical memory, specifically for an MDL. A driver calls this function to allocate physical memory from a particular address range. Do not use this function to allocate memory for DMA; use the system’s DMA routines instead.
This function might return fewer pages than the caller requested. Therefore, the driver must call MmGetMdlByteCount to verify the number of bytes allocated.
MmGetSystemAddressForMdlSafe
Maps the physical pages described by an MDL into system space and returns a virtual address for the MDL.
The returned virtual address can be used at any IRQL and in any process context.
IoBuildPartialMdl
Maps part of a buffer described by an existing MDL into a new MDL that the driver previously allocated by calling IoAllocateMdl.
MmAdvanceMdl
Increases the starting address of an MDL.
A driver calls this function to update the MDL to describe a partial buffer when I/O operations are not (or cannot be) completed, either because not enough memory is available or because the device can write only part of the buffer at a time.
MmGetMdlVirtualAddress
Returns the starting virtual address of an MDL.
IoFreeMdl
Frees an MDL that was previously allocated by IoAllocateMdl.
MmFreePagesFromMdl
Frees the pages described by an MDL that was previously created by MmAllocatePagesForMdl.


0 komentar:

Posting Komentar

 

Serba Ada Blog Copyright © 2011-2012 | Powered by Blogger