虚拟内存地址区域

姓名

vm_address_region - 虚拟内存地址空间的连续区域

SYNOPSIS

虚拟内存地址区域 (VMAR) 代表虚拟机 地址空间

说明

内核和用户空间使用 VMAR 来表示 地址空间

每个进程都始于一个涵盖整个整个云生命周期的 VMAR(根 VMAR) 地址空间(请参阅 zx_process_create())。每个 VMAR 逻辑上可分成任意数量的不重叠的部分,每个部分 代表子 VMAR、虚拟内存映射或间隔子 VMAR 使用 zx_vmar_allocate() 创建。虚拟机映射 使用 zx_vmar_map() 创建。

VMAR 采用分层权限模型,用于提供允许的映射权限。 例如,根 VMAR 允许读取、写入和可执行映射。一个 可以创建一个仅允许读写映射的子级 VMAR,其中 创建允许可执行映射的子文件是违法的。

使用 zx_vmar_allocate() 创建 VMAR 时,其父级 VMAR 会保留引用 。因此,如果子级 VMAR 的所有句柄都已关闭,则子级 VMAR 的 及其后代在地址空间中将保持活动状态。为此, 断开子级与地址空间的连接,zx_vmar_destroy() 必须在子节点的句柄上调用。

默认情况下,所有地址空间分配都是随机分配的。在 VMAR 创建时间,调用方可以选择使用哪种随机算法。 默认分配器会尝试在整个 VMAR 的宽度。备用分配器,通过 ZX_VM_COMPACT:尝试让分配在 VMAR,但位于范围内的随机位置。建议使用 默认分配器。

VMAR 可以选择支持固定偏移的映射模式(称为特定映射)。 此模式可用于创建保护页或确保 映射。每个 VMAR 可能具有 ZX_VM_CAN_MAP_SPECIFIC 权限, 无论其父级 VMAR 是否具有该权限。

示例

#include <zircon/syscalls.h>

/* Map this VMO into the given VMAR, with |before| bytes of unmapped guard space
   before it and |after| bytes after it.  */
zx_status_t map_with_guard(zx_handle_t vmar, size_t before, size_t after,
                           zx_handle_t vmo, uint64_t vmo_offset,
                           size_t mapping_len, uintptr_t* mapped_addr,
                           zx_handle_t* wrapping_vmar) {

    /* wrap around check elided */
    const size_t child_vmar_size = before + after + mapping_len;
    const zx_vm_option_t child_vmar_options = ZX_VM_CAN_MAP_READ |
                                              ZX_VM_CAN_MAP_WRITE |
                                              ZX_VM_CAN_MAP_SPECIFIC;
    const zx_vm_option_t mapping_options = ZX_VM_SPECIFIC |
                                           ZX_VM_PERM_READ |
                                           ZX_VM_PERM_WRITE;

    uintptr_t child_vmar_addr;
    zx_handle_t child_vmar;
    zx_status_t status = zx_vmar_allocate(vmar, child_vmar_options, 0,
                                          child_vmar_size,
                                          &child_vmar,
                                          &child_vmar_addr);
    if (status != ZX_OK) {
        return status;
    }

    status = zx_vmar_map(child_vmar, mapping_options, before, vmo, vmo_offset,
                         mapping_len, mapped_addr);
    if (status != ZX_OK) {
        zx_vmar_destroy(child_vmar);
        zx_handle_close(child_vmar);
        return status;
    }

    *wrapping_vmar = child_vmar;
    return ZX_OK;
}

查看其他

SYSCALL