摘要
建立 VM 物件的子項。
宣告
#include <zircon/syscalls.h>
zx_status_t zx_vmo_create_child(zx_handle_t handle,
uint32_t options,
uint64_t offset,
uint64_t size,
zx_handle_t* out);
說明
zx_vmo_create_child()
會建立新的虛擬記憶體物件 (VMO),成為現有 vmo 的子項。語意的行為取決於子項的類型。
成功時會傳回一個控制代碼,代表含有要求大小的物件。
options 必須包含下列其中一個標記,才能指定子項類型:
ZX_VMO_CHILD_SNAPSHOT
- 建立子項,使其行為就像執行緊急副本一樣。當寫入發生時,父項和子項都會執行延遲複本。延遲複製可讓子項和父項互相區別。在父項 VMO 大小範圍之外的任何讀取作業都含有零,且會寫入新的零填入頁面。以下項目不支援這個標記:- 設有固定區域的 VMO。
- 以
zx_vmo_create_physical()
或zx_vmo_create_contiguous()
為基礎或遞減建立的 VMO - 由使用者呼叫器支援的 VMO。 如要瞭解 VMO 系統呼叫與子項的互動,請參閱「附註」。
啟用 ZX_VMO_CHILD_NO_WRITE 選項且停用 ZX_VMO_CHILD_RESIZABLE 選項時,ZX_VMO_CHILD_SNAPSHOT 會建立不可變更的 VMO。
ZX_VMO_CHILD_SNAPSHOT_AT_LEAST_ON_WRITE
- 建立子項,至少對寫入語意進行複製。子項的任何寫入作業都會從父項取得頁面副本,其內容可能會與父項不同。在頁面寫入及複製之前,系統允許讀取作業,但不保證一定能在父項執行寫入作業時傳回變更值。此旗標可能無法用於透過zx_vmo_create_physical()
、zx_vmo_create_contiguous()
或這類 VMO 的子系建立的 VMO。如要瞭解 VMO 系統呼叫與子項的互動,請參閱「附註」。
ZX_VMO_CHILD_SNAPSHOT_MODIFIED
- 建立子項,使其行為就像在上層沒有分頁器支援的任何頁面上執行 (也就是由已呼叫頁面 VMO 的子項修改過的頁面)。採用 Pager 的頁面將至少具備「寫入時複製」語意。這個標記可能不適用於透過 zx_vmo_create_physical()
、zx_vmo_create_contiguous()
、含有固定頁面的 VMO,或這類 VMO 的子系建立的 VMO。如果使用 SNAPSHOT_AT_LEAST_ON_WRITE
建立具有非配量子項或非分頁式 VMO 子項,也不支援這個標記。如要瞭解 VMO 系統呼叫與子項的互動,請參閱「附註」。
ZX_VMO_CHILD_SLICE
- 建立具有直接讀取/寫入權限父項區段的配量。配量 VMO 的所有作業都會以在父項上完成的方式運作。切片和父項 VMO 的重複控制代碼不同,前者僅允許存取父項 VMO 子範圍,並允許使用ZX_VMO_ZERO_CHILDREN
信號。這個標記可與透過zx_vmo_create_physical()
或zx_vmo_create_contiguous()
及其子系建立的 VMO 搭配使用。這個標記可能無法與使用ZX_VMO_RESIZABLE
選項建立的 VMO 搭配使用。ZX_VMO_CHILD_REFERENCE
- 建立 VMO 的參照。在參考 VMO 上的所有作業,其行為就像是在父項上完成一樣。參照一律橫跨父項,而 offset 和 size 必須為 0。如果使用者想使用ZX_VMO_ZERO_CHILDREN
信號追蹤 VMO 的待處理參照,這個方法就能派上用場。如要進一步瞭解這個信號,請參閱「附註」。此旗標可能無法用於透過zx_vmo_create_physical()
、zx_vmo_create_contiguous()
或這類 VMO 的子系建立的 VMO。
此外,options 可包含零或多個下列標記,進一步指定子項的行為:
ZX_VMO_CHILD_RESIZABLE
:建立可調整大小的子項 VMO。這與ZX_VMO_CHILD_SLICE
不相容。ZX_VMO_CHILD_NO_WRITE
- 建立無法寫入的子項。這與ZX_VMO_CHILD_RESIZABLE
不相容。
offset 必須對齊頁面。
offset + size 不得超過 64 位元未正負號值的範圍。
無論是位移或大小,開頭或大小都可能會超出原始 VMO 的大小。
VMO 的大小會四捨五入至下一個頁面大小邊界。
VMO 的內容大小會初始化為指定的 (未四捨五入) 大小。將 zx_object_get_property()
與 ZX_PROP_VMO_CONTENT_SIZE
搭配使用,可讀取 VMO 的內容大小。將 zx_object_set_property()
與 ZX_PROP_VMO_CONTENT_SIZE
搭配使用可設定 VMO 的內容大小,不必實際調整 VMO 大小。
根據預設,子項帳號代碼的權利將與原始帳號相同,但有幾個例外。請參閱 zx_vmo_create()
以取得相關詳細資料的討論。
如果 options 包含 ZX_VMO_CHILD_RESIZABLE
,系統就會新增 ZX_RIGHT_RESIZE
。
如果是 ZX_VMO_CHILD_REFERENCE
,ZX_VMO_CHILD_RESIZABLE
選項可控制是否要使用 out 中傳回的參照控點調整父項 VMO 的大小。如果父項 VMO 可以調整大小,無論 ZX_VMO_CHILD_RESIZABLE
為何,參照都會在父項 VMO 上看見大小調整。不過,只有在父項 VMO 可以調整大小時才支援 ZX_VMO_CHILD_RESIZABLE
,也就是無法建立可調整大小的 VMO 參照。
在所有情況下,如果設定了 ZX_VMO_NO_WRITE
,系統就會移除 ZX_RIGHT_WRITE
。
如果 options 為 ZX_VMO_CHILD_SNAPSHOT
、ZX_VMO_CHILD_SNAPSHOT_AT_LEAST_ON_WRITE
或 ZX_VMO_CHILD_SNAPSHOT_MODIFIED
,且未設定 ZX_VMO_CHILD_NO_WRITE
,則系統會新增 ZX_RIGHT_WRITE
並移除 ZX_RIGHT_EXECUTE
。
附註
建立子 VMO 會導致現有 (來源) VMO ZX_VMO_ZERO_CHILDREN
信號變為停用狀態。只有在最後一個子項遭到刪除,且這些子項都沒有對應至位址空間時,ZX_VMO_ZERO_CHILDREN
才會再次生效。
非配量子項 VM 會以下列方式與 VMO 系統呼叫互動:
- 子項的
zx_vmo_op_range()
COMMIT 模式會將內容提交至子項的網頁,使其內容與上層的對應頁面相同。如果這些網頁是由 Pager 提供,這項作業也會修訂父項中的這些網頁。否則,如果這些頁面沒有在父項修訂,零填入的頁面將直接視為子項,而不會影響父項。 - 系統不支援
zx_vmo_op_range()
的 DECOMMIT 模式。
權限
handle 必須是 ZX_OBJ_TYPE_VMO
類型,且包含 ZX_RIGHT_DUPLICATE
,且有 ZX_RIGHT_READ
。
傳回值
zx_vmo_create_child()
在成功時傳回 ZX_OK
。如果失敗,系統會傳回負值的錯誤值。
錯誤
ZX_ERR_BAD_TYPE
輸入控制代碼不是 VMO。
ZX_ERR_ACCESS_DENIED
輸入帳號代碼權限不足。
ZX_ERR_INVALID_ARGS
out 是無效的指標或 NULL,或是未對齊頁面對齊,或提供的選項組合不相容。
ZX_ERR_OUT_OF_RANGE
偏移 + size 過大。
ZX_ERR_NO_MEMORY
由於記憶體不足而失敗。使用者空間無法妥善處理這項 (不太可能) 錯誤。日後的建構作業就不會再發生這個錯誤。
ZX_ERR_BAD_STATE
vmo 有部分固定頁面,因此無法建立 COW 子項。
ZX_ERR_NOT_SUPPORTED
輸入控點是可捨棄的 VMO,或輸入控點是可調整大小的 VMO,而「選項」包含 ZX_VMO_CHILD_SLICE
。
另請參閱
zx_vmar_map()
zx_vmo_create()
zx_vmo_get_size()
zx_vmo_op_range()
zx_vmo_read()
zx_vmo_set_size()
zx_vmo_write()