JustKernel

Ray Of Hope

Memory Descriptor List

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.

Drivers create MDLs in the following situations:

  •  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 the METHOD_NEITHER I/O, a pointer to a buffer is part of the request. If the originaor 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 funciton returns a valid system-space virtual address with which the driver can safely access he 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 IoBuildParticalMdl 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 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.

Some of the MDL functions :

MmAllocateMappingAddress

IoAllocateMdl

MmProbeAndLockPages

MmBuildMdlForNonPagedPool

MmAllocatePagesForMdl

MmGetSystemAddressForMdlSafe

IoBuildparticalMdl

MmAdvanceMdl

MmGetMdlVirtualAddress.

Originally Posted On:  2010-04-24 01:48:19

Anshul Makkar, anshul_makkar@justkernel.com

Tags:


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.