KasperskyOS Community Edition 1.3

Allocating and freeing memory

Information about API functions is provided in the table below.

Using the API

Virtual memory pages may be free, reserved, or committed. Free pages that are used to allocate a virtual memory region become reserved pages. Reserved pages may or may not be mapped to physical memory. Reserved pages that are mapped to physical memory are committed pages.

Pages of a virtual memory region that are allocated by the KnVmAllocate() function call can be committed in three different ways:

  1. Fully committed when the region is allocated.
  2. Fully or partially committed after allocation of the region (by calling the KnVmCommit() function).
  3. Committed whenever virtual addresses are queried (so-called "lazy" mode).

When the first option is used, the entire required volume of physical memory is allocated immediately after the virtual memory region is reserved. When the second or third option is used, the virtual memory region is reserved without allocating physical memory. This lets you conserve physical memory if a reserved virtual memory region will not actually be required or will only be partially used. In addition, a virtual memory region can be allocated faster if its allocation does not include commitment.

When in "lazy" mode, physical memory is allocated only when the virtual memory region is actually queried. In this case, the page containing the queried address and several pages before and after this address are committed.

If you call the KnVmAllocate() function with the VMM_FLAG_COMMIT and VMM_FLAG_LOCKED flags, the virtual memory region will be reserved and fully committed. If you call the KnVmAllocate() function with the VMM_FLAG_COMMIT flag but without the VMM_FLAG_LOCKED flag, the virtual memory region will be reserved and committed only in "lazy" mode. If you call the KnVmAllocate() function with the VMM_FLAG_LOCKED flag but without the VMM_FLAG_COMMIT flag, the virtual memory region will be reserved without commitment and a subsequent call of the KnVmCommit() function will fully commit this region. If you call the KnVmAllocate() function without the VMM_FLAG_COMMIT and VMM_FLAG_LOCKED flags, the virtual memory region will be reserved without commitment and a subsequent call of the KnVmCommit() function will commit this region in "lazy" mode.

A virtual memory region is allocated when the MDL buffer, DMA buffer or MMIO memory region is mapped to process memory. This region is allocated by the mapping function.

A protected page may reside at the beginning and/or end of the virtual memory region. This page is never committed. Any query of this page will result in an exception signaling that the region boundaries have been exceeded.

To change the access rights to the virtual memory region, call the KnVmProtect() function. You can fully close and then re-open access to a region while retaining is contents.

To free physical memory while retaining the reservation of virtual addresses, call the KnVmDecommit() or KnVmReset() function. In this case, the contents of the virtual memory region will be lost. After freeing physical memory by calling the KnVmDecommit() function, you must call the KnVmCommit() function to subsequently use the virtual memory region. After freeing physical memory by calling the KnVmReset() function, the virtual memory region can be used without any additional actions required. This virtual memory region will correspond to memory allocated by calling the KnVmAllocate() function with the VMM_FLAG_COMMIT flag but without the VMM_FLAG_LOCKED flag.

The KnVmProtect(), KnVmDecommit(), and KnVmReset() functions cannot be used if the MDL buffer, DMA buffer or MMIO memory region is mapped to the virtual memory region.

To free the virtual memory region, call the KnVmUnmap() function. When this function is called, the reserved pages will become free regardless of whether or not they were committed, and the physical memory mapped to committed pages is also freed.

The KnVmUnmap() function frees the virtual addresses of a region mapped to the MDL buffer, but does not delete the MDL buffer. In addition, this function cannot be used if the DMA buffer or MMIO memory region is mapped to the virtual memory region.

The KnVmCommit(), KnVmProtect(), KnVmDecommit(), KnVmReset(), and KnVmUnmap() functions can be applied for the entire allocated virtual memory region or for a portion of it.

The functions presented in this section provide the basis for implementing memory allocation/deallocation functions of the libkos library, and functions of POSIX interfaces such as malloc(), calloc(), realloc(), free(), mmap(), and munmap().

Information about API functions

vmm_api.h functions

Function

Information about the function

KnVmAllocate()

Purpose

Allocates (reserves and optionally commits) a virtual memory region.

Parameters

  • [in,optional] addr – page-aligned, preferred base address of the virtual memory region, or 0 to select this address automatically.
  • [in] size – size of the virtual memory region in bytes. It must be a multiple of the memory page size.
  • [in] flags – flags defining the parameters of the virtual memory region. The flags are defined in the header file sysroot-*-kos/include/vmm/flags.h from the KasperskyOS SDK.

Returned values

If successful, the function returns the base address of the allocated virtual memory region, otherwise it returns RTL_NULL.

Additional information

In the flags parameter, you can specify the following flags:

  • VMM_FLAG_COMMIT – commits the virtual memory region in "lazy" mode, whereby the physical memory pages are allocated as virtual addresses are queried.
  • VMM_FLAG_LOCKED – commits the virtual memory region while allocating the entire required volume of physical memory.
  • VMM_FLAG_READ, VMM_FLAG_WRITE, VMM_FLAG_EXECUTE and VMM_FLAG_RWX_MASK – flags defining the access rights to the virtual memory region.
  • VMM_FLAG_LOW_GUARD, VMM_FLAG_HIGH_GUARD – adds a protected page to the beginning and end of the virtual memory region, respectively. The size of the protected page is not included in the size of the virtual memory region.
  • VMM_FLAG_GROW_DOWN – defines the direction in which the virtual memory is mapped to physical memory when "lazy" commitment mode is applied. If this flag is set, the virtual memory page containing the queried address and several preceding pages are mapped to physical memory. If this flag is not set, the virtual memory page containing the queried address and several subsequent pages are mapped to physical memory.

Permissible combinations of flags defining the access rights to the virtual memory region:

  • VMM_FLAG_READ – read access.
  • VMM_FLAG_READ | VMM_FLAG_WRITE – read-and-write access.
  • VMM_FLAG_READ | VMM_FLAG_EXECUTE – read-and-execute access.
  • VMM_FLAG_RWX_MASK or VMM_FLAG_READ | VMM_FLAG_WRITE | VMM_FLAG_EXECUTE – read/write/execute access.

KnVmCommit()

Purpose

Commits a virtual memory region.

Parameters

  • [in] addr – page-aligned base address of the virtual memory region.
  • [in] size – size of the virtual memory region in bytes. It must be a multiple of the memory page size.

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.

KnVmDecommit()

Purpose

Decommits a virtual memory region.

Parameters

  • [in] addr – page-aligned base address of the virtual memory region.
  • [in] size – size of the virtual memory region in bytes. It must be a multiple of the memory page size.

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.

KnVmProtect()

Purpose

Modifies the access rights to the virtual memory region.

Parameters

  • [in] addr – page-aligned base address of the virtual memory region.
  • [in] size – size of the virtual memory region in bytes. It must be a multiple of the memory page size.
  • [in] newFlags – flags defining the access rights to the virtual memory region. The flags are defined in the header file sysroot-*-kos/include/vmm/flags.h from the KasperskyOS SDK.

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.

Additional information

In the newFlags parameter, you can specify the following combinations of flags:

  • VMM_FLAG_READ – read access.
  • VMM_FLAG_READ | VMM_FLAG_WRITE – read-and-write access.
  • VMM_FLAG_READ | VMM_FLAG_EXECUTE – read-and-execute access.
  • VMM_FLAG_RWX_MASK or VMM_FLAG_READ | VMM_FLAG_WRITE | VMM_FLAG_EXECUTE – read/write/execute access.
  • 0 – access denied.

KnVmUnmap()

Purpose

Frees up the virtual memory region.

Parameters

  • [in] addr – page-aligned base address of the virtual memory region.
  • [in] size – size of the virtual memory region in bytes. It must be a multiple of the memory page size.

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.

KnVmQuery()

Purpose

Gets information about a virtual memory page.

Parameters

  • [in] addr – address included in the virtual memory page.
  • [out] info – pointer to the structure containing information about the virtual memory page. The type of structure is defined in the header file sysroot-*-kos/include/vmm/info.h from the KasperskyOS SDK.

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.

KnVmReset()

Purpose

Decommits a virtual memory region.

Parameters

  • [in] addr – page-aligned base address of the virtual memory region.
  • [in] size – size of the virtual memory region in bytes. It must be a multiple of the memory page size.

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.