摘要
添加内存映射。
声明
#include <zircon/syscalls.h>
zx_status_t zx_vmar_map(zx_handle_t handle,
zx_vm_option_t options,
size_t vmar_offset,
zx_handle_t vmo,
uint64_t vmo_offset,
size_t len,
zx_vaddr_t* mapped_addr);
说明
将给定 VMO 映射到给定的虚拟内存地址区域。映射 会保留对底层虚拟内存对象的引用,这意味着 关闭 VMO 句柄不会移除此函数添加的映射。
options 是以下内容的位矢量:
ZX_VM_SPECIFIC
使用 vmar_offset 放置映射,如果存在 handle 不具备ZX_VM_CAN_MAP_SPECIFIC
权限。 vmar_offset 是相对于给定 VMAR 基地址的偏移量。 指定的范围与其他 VMAR 或映射重叠是错误的。ZX_VM_SPECIFIC_OVERWRITE
与ZX_VM_SPECIFIC
相同,但可以 与其他映射重叠与另一个 VMAR 部分重叠仍为错误。 如果该范围符合上述要求,它将以原子方式进行(相对于所有 替换范围内的现有映射 由 vmar_offset 和 len 指定。如果该范围与任意一项重叠 映射,那么范围外的映射部分将仍为映射关系。ZX_VM_OFFSET_IS_UPPER_LIMIT
将 vmar_offset 解释为上限 用于限制内核对偏移量的选择,如果是 handle,则无效 没有ZX_VM_CAN_MAP_SPECIFIC
权限。生成的映射 将具有偏移值 + len(小于等于 vmar_offset)。此选项不能 如果使用了ZX_VM_SPECIFIC
或ZX_VM_SPECIFIC_OVERWRITE
,则指定此参数。ZX_VM_PERM_READ
将 vmo 映射为可读状态。如果 handle 没有ZX_VM_CAN_MAP_READ
权限,handle 具有ZX_RIGHT_READ
不正确,或者 vmo 句柄没有 右边ZX_RIGHT_READ
。ZX_VM_PERM_WRITE
将 vmo 映射为可写入。如果 handle 没有ZX_VM_CAN_MAP_WRITE
权限,handle 具有ZX_RIGHT_WRITE
不正确,则 vmo 句柄没有ZX_RIGHT_WRITE
,或者 options 不指定ZX_VM_PERM_READ
。ZX_VM_PERM_EXECUTE
将 vmo 映射为可执行文件。如果 handle 没有ZX_VM_CAN_MAP_EXECUTE
权限,handle 句柄具有权限ZX_RIGHT_EXECUTE
不正确,则 vmo 句柄没有ZX_RIGHT_EXECUTE
,或者 options 不指定ZX_VM_PERM_READ
。ZX_VM_MAP_RANGE
立即转到所有支持的新映射 VMO 的各区域。如果出现以下情况,则无法指定此项:ZX_VM_SPECIFIC_OVERWRITE
。ZX_VM_ALLOW_FAULTS
必需(如果可以创建) 映射以生成故障。特别是,如果 vmo 可调整大小,则必须使用此属性, 如果 vmo 不可调整大小,但映射超出了 vmo 的末尾,则 vmo 可舍弃,或者 vmo 是通过zx_pager_create_vmo()
创建的。ZX_VM_PERM_READ_IF_XOM_UNSUPPORTED
将 vmo 映射到可读状态(如果系统执行该操作) 不支持映射只执行页面。如果系统可以映射只执行 则忽略此标志。ZX_VM_REQUIRE_NON_RESIZABLE
如果 vmo 可调整大小,则失败。
如果 options 不包含 ZX_VM_SPECIFIC
,则 vmar_offset 必须为 0,
已设置 ZX_VM_SPECIFIC_OVERWRITE
或 ZX_VM_OFFSET_IS_UPPER_LIMIT
。
ZX_VM_OFFSET_IS_UPPER_LIMIT
用于限制选择范围,以及
在其他情况下,行为与 ZX_VM_SPECIFIC
和
已设置 ZX_VM_SPECIFIC_OVERWRITE
,并为映射分配了一个偏移量
(分配器由内核上设置的政策决定)
目标 VMAR)。
len 必须为非零并页面对齐。
此外,还可以添加以下二次幂对齐标志之一:
ZX_VM_ALIGN_1KB
将 child_addr 与至少 1K 字节的 2 次方对齐。ZX_VM_ALIGN_2KB
将 child_addr 与至少 2K 字节的 2 幂对齐。ZX_VM_ALIGN_4KB
将 child_addr 与至少 4K 字节的 2 次方对齐。ZX_VM_ALIGN_8KB
将 child_addr 与至少 8K 字节的 2 幂对齐。 并持续到ZX_VM_ALIGN_4GB
将 child_addr 与至少 4G 字节的 2 次方对齐。
如果 vmar,将 ZX_VM_ALIGN
标志与 ZX_VM_SPECIFIC
搭配使用将会失败
基准地址 + vmo_offset 与请求的值不一致。
权限
handle 的类型必须为 ZX_OBJ_TYPE_VMAR
。
vmo 的类型必须为 ZX_OBJ_TYPE_VMO
。
返回值
zx_vmar_map()
会返回 ZX_OK
以及
映射(通过 mapped_addr)。基准地址将与页面对齐
和非零值。如果失败,则返回负的错误值。
错误
ZX_ERR_BAD_HANDLE
handle 或 vmo 不是有效的句柄。
ZX_ERR_WRONG_TYPE
handle 或 vmo 分别不是 VMAR 或 VMO 句柄。
ZX_ERR_BAD_STATE
句柄是指已销毁的 VMAR。
ZX_ERR_INVALID_ARGS
表示以下任意一项:
- mapped_addr 或 options 无效。
- vmar_offset 在 ZX_VM_SPECIFIC
、ZX_VM_SPECIFIC_OVERWRITE
或
已指定 ZX_VM_OFFSET_IS_UPPER_LIMIT
。
- 同时指定了 ZX_VM_SPECIFIC_OVERWRITE
和 ZX_VM_MAP_RANGE
。
- ZX_VM_OFFSET_IS_UPPER_LIMIT
与 ZX_VM_SPECIFIC
中的任一项一起指定
或 ZX_VM_SPECIFIC_OVERWRITE
。
- vmar_offset 和 len 表示因超出区域边界而不能满足的分配情况。
- vmar_offset 或 vmo_offset 未对齐页面。
- len 为 0 或未页面对齐。
已指定 ZX_ERR_ALREADY_EXISTS
个ZX_VM_SPECIFIC
,但未指定
ZX_VM_SPECIFIC_OVERWRITE
,并且请求的范围与另一个映射重叠。
ZX_ERR_NO_RESOURCES
如果在 VMAR 中找不到位置以创建映射。
ZX_ERR_ACCESS_DENIED
权限不足,无法完成请求的映射。
ZX_ERR_NOT_SUPPORTED
:vmo 可调整大小、可舍弃或由分页器支持,但
未设置 ZX_VM_ALLOW_FAULTS
。
ZX_ERR_NOT_SUPPORTED
:如果 vmo 可调整大小且已设置 ZX_VM_REQUIRE_NON_RESIZABLE
。
ZX_ERR_BUFFER_TOO_SMALL
VMO 不可调整大小,并且映射超出末尾
但未设置 ZX_VM_ALLOW_FAULTS
。
ZX_ERR_NO_MEMORY
因内存不足而失败。
用户空间没有好办法处理这种(不太可能)错误。
在将来的版本中,此错误不会再发生。
ZX_ERR_OUT_OF_RANGE
vmo_offset + ROUNDUP(len, PAGE_SIZE)
溢出。
备注
可以将支持内存映射的 VMO 的大小调整为更小的大小。这可能会导致
线程正在对错误的 VMAR 区域执行读取或写入操作。为了避免这种危险,
从客户端接收 VMO 的客户端在映射时应使用 ZX_VM_REQUIRE_NON_RESIZABLE
VMO。