Miscellaneous Page Management Services

A virtual device must not modify page tables directly. However, a virtual device can retrieve a copy of a page table to analyze. To do so, use the _CopyPageTable service.

Virtual device drivers (VxDs) which need to communicate with hardware devices may have need to convert a linear address (such as one provided by an application) into a physical address. Accomplish this using the following steps:

  1. Lock the memory to prevent its physical address from changing. This can typically be accomplished via the LinPageLock() service.
  2. Use CopyPageTable() to access the page table information, which includes the physical address.
  3. Use the values obtained in step (2) to program the hardware device.
  4. When the physical address is no longer needed (when the I/O operation has completed), unlock the memory (typically via LinPageUnlock()). Note that once the pages have been unlocked, the values obtained in step (2) are no longer valid.

Example:

;
; This code fragment illustrates how a linear address can be converted
; to a physical address.
;
; It converts the 3 pages starting at pgStart to a physical address.
; (Page numbers are equal to linear addresses shifted right by 12.
; One page is equal to 4K.)
;
    sub    esp, 3 * 4        ; temporary buffer for CopyPageTable

    VMMCall    _LinPageLock, <pgStart, 3, 0>
    test    eax, eax    
    jz    error            ; could not lock the memory

    mov    esi, esp
    VMMCall    _CopyPageTable, <pgStart, 5, esi, 0>
    test    eax, eax
    jz    errorUnlock        ; unexpected error
                    ; go straight to unlock
;
;    Use the values obtained by CopyPageTable.  For this sample,
;    we merely print them to the debugging terminal.
;

    mov    eax, [esi][0]
    and    eax, NOT 0FFFh
    Trace_Out "Page pgStart is at physical address #EAX"

    mov    eax, [esi][4]
    and    eax, NOT 0FFFh
    Trace_Out "Page pgStart+1 is at physical address #EAX"

    mov    eax, [esi][8]
    and    eax, NOT 0FFFh
    Trace_Out "Page pgStart+2 is at physical address #EAX"

;
;    We are now finished with the physical addresses.  Release
;    the lock to tell the memory manager that it's okay to move
;    the pages in memory again.
;
errorUnlock:
    VMMCall    _LinPageUnlock, <pgStart, 3, 0>

error:
    add    esp, 3 * 4        ; clean the stack
 

To retrieve high-level information about a range of pages, use the _PageQuery function.

Each committed page has a specific set of permissions, which determine whether the page can be written to and whether it is accessible in user mode (ring 3). To change the permissions for a range of pages, use the _PageModifyPermissions service.

Because zero is a valid address, you should use an address in the permanently invalid region of linear address space to denote an invalid pointer.

See Also

_CopyPageTable, _GetNulPageHandle, _PageModifyPermissions, _PageQuery