摘要
新增記憶體對應。
宣告
#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_base + vmar_offset。如果使用- ZX_VM_SPECIFIC或- ZX_VM_SPECIFIC_OVERWRITE,則無法指定這個選項。
- ZX_VM_PERM_READ將 vmo 設為可讀。如果句柄沒有- ZX_VM_CAN_MAP_READ權限、句柄沒有- ZX_RIGHT_READ權限,或是 vmo 句柄沒有- ZX_RIGHT_READ權限,就會發生錯誤。
- ZX_VM_PERM_WRITE將 vmo 對應為可寫入。如果句柄沒有- ZX_VM_CAN_MAP_WRITE權限、句柄沒有- ZX_RIGHT_WRITE權限、vmo 句柄沒有- ZX_RIGHT_WRITE權限,或是選項未指定- 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 可調整大小、已設定- ZX_VM_FAULT_BEYOND_STREAM_SIZE、vmo 無法調整大小但對應項目超出 vmo 的結尾、vmo 可捨棄,或是 vmo 是從- zx_pager_create_vmo()建立,就需要使用此方法。
- ZX_VM_PERM_READ_IF_XOM_UNSUPPORTED如果系統不支援對應執行專用網頁,請將 vmo 對應為可讀。如果系統可以對應執行權限,則會忽略此標記。
- ZX_VM_REQUIRE_NON_RESIZABLE如果 vmo 可調整大小,則會失敗。
- ZX_VM_FAULT_BEYOND_STREAM_SIZE超過流量大小 (四捨五入至頁面邊界) 的記憶體存取作業會發生錯誤。需要- ZX_VM_ALLOW_FAULTS。
如果選項未設定 ZX_VM_SPECIFIC、ZX_VM_SPECIFIC_OVERWRITE 或 ZX_VM_OFFSET_IS_UPPER_LIMIT,vmar_offset 必須為 0。ZX_VM_OFFSET_IS_UPPER_LIMIT 可用於限制選取範圍,否則會與未設定 ZX_VM_SPECIFIC 或 ZX_VM_SPECIFIC_OVERWRITE 的情況類似,其中對應項目會由核心隨機指派偏移量 (由目標 VMAR 上設定的政策決定的配置器)。
len 必須不為零,且會在內部四捨五入,以便對齊頁面。
此外,您也可以新增下列其中一個 2 次方對齊標記:
- ZX_VM_ALIGN_1KB會將 child_addr 對齊至至少 1 KB 的 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 基礎位址 + vmo_offset 與要求的值不一致,使用 ZX_VM_ALIGN 標記搭配 ZX_VM_SPECIFIC 會失敗。
權限
handle 必須是 ZX_OBJ_TYPE_VMAR 類型。
vmo 必須是 ZX_OBJ_TYPE_VMO 類型。
傳回值
zx_vmar_map() 會在成功時傳回 ZX_OK 和對應的絕對基底位址 (透過 mapped_addr)。基底位址會與頁面對齊,且不為零。如果失敗,系統會傳回負值錯誤。
錯誤
ZX_ERR_BAD_HANDLE  handle 或 vmo 不是有效的 handle。
ZX_ERR_WRONG_TYPE  handle 或 vmo 分別不是 VMAR 或 VMO handle。
ZX_ERR_BAD_STATE  handle 是指已銷毀的 VMAR。
ZX_ERR_INVALID_ARGS 適用於下列任一情況:
- mapped_addr 或 options 無效。
 - 如未指定 ZX_VM_SPECIFIC、ZX_VM_SPECIFIC_OVERWRITE 或 ZX_VM_OFFSET_IS_UPPER_LIMIT,vmar_offset 會設為非零值。- 同時指定 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_VM_FAULT_BEYOND_STREAM_SIZE 已設定,且 vmo 為實體或連續。
ZX_ERR_BUFFER_TOO_SMALL VMO 無法調整大小,且對應項目超出 VMO 的結尾,但未設定 ZX_VM_ALLOW_FAULTS。
ZX_ERR_NO_MEMORY 記憶體不足導致失敗。使用者空間沒有適當的方式來處理這個 (不太可能發生的) 錯誤。日後的版本將不會再發生這個錯誤。
ZX_ERR_OUT_OF_RANGE vmo_offset + ROUNDUP(len, PAGE_SIZE) 溢位。
附註
支援記憶體對應的 VMO 可縮小至較小的大小。這可能會導致執行緒讀取或寫入 VMAR 區域時發生錯誤。為避免這項風險,從用戶端接收 VMOs 的服務應在對應 VMO 時使用 ZX_VM_REQUIRE_NON_RESIZABLE。