MDL
https://www.osronline.com/article.cfm?id=423
An MDL is a structure that describes the fixed physical memory locations that comprise a contiguous data buffer in virtual memory.
Each MDL can only describe a single virtually contiguous data buffer.
The data buffer that the MDL describes can be in either a kernel virtual address space, user virtual address space, or both.
The MDL describes the data buffer at a fixed position in physical memory. In other words, the data buffer an MDL describes will always be paged in (resident), and its pages will be locked-down ("pinned"). This means the data buffer can neither be paged out nor moved. These pages will remain locked for the lifetime of the MDL.
The data buffer that the MDL describes does not need to be page aligned, nor does it need to be an integral number of pages in length.
//
// An MDL describes pages in a virtual buffer in terms
// of physical pages. The pages associated with the
// buffer are described in an array that is allocated
// just after the MDL header structure itself.
//
// One simply calculates the base of the array by
// adding one to the base MDL pointer:
//
// Pages = (PPFN_NUMBER) (Mdl + 1);
//
// Notice that while in the context of the subject
// thread, the base virtual address of a buffer mapped
// by an MDL may be referenced using the following:
//
// Mdl->StartVa | Mdl->ByteOffset
//
typedef struct _MDL {
struct _MDL *Next;
CSHORT Size;
CSHORT MdlFlags;
struct _EPROCESS *Process;
PVOID MappedSystemVa;
PVOID StartVa;
ULONG ByteCount;
ULONG ByteOffset;
} MDL, *PMDL;
From the comment you know the MDL is actually a variable length structure with an array that contains the underlying physical pages of the address range at the tail. Also you know that StartVa is the page aligned virtual address of the start of the range and ByteOffset is the starting offset into the first page.
Building and using MDLs.
Step1: Allocating the Structure -- use the IoAllocateMdl DDI
Step2:Probing and Locking --- MmProbeAndLockPages DDI
Step3: Mapping
your driver wants a new virtual address for accessing the underlying pages ---MmMapLockedPagesSpecifyCache
you want a kernel virtual address for this MDL---MmGetSystemAddressForMdlSafe macro