虛擬化總覽

Fuchsia 的虛擬化堆疊提供 有些人會將 Cloud Storage 視為檔案系統 但實際上不是Zircon 會實作 Type-2 管理程序, 會公開 syscall,以便使用者空間元件建立及設定 CPU 和 記憶體虛擬化功能虛擬機器管理工具 (VMM) 元件是以 管理程序的頂部,透過定義記憶體映射來組合虛擬機器 設定陷阱、模擬各種裝置和周邊裝置。訪客管理員 接著,元件就位於 VMM 上方,提供訪客專屬的二進位檔及 此外還會從 0 自動調整資源配置 您完全不必調整資源調度設定Fuchsia 目前支援 3 種房客套裝方案;未經修改的 Debian 訪客、Zircon 訪客和 Termina 式 Linux 訪客。

搭載 VMX 的 Intel x64 裝置支援 Fuchsia 虛擬化功能 已啟用且大部分可以啟動至 EL2 的 arm64 (ARMv8.0 及以上) 裝置。 請注意,系統目前不支援 AMD SVM。

顯示虛擬化元件的圖表

管理程序

管理程序公開 syscall 以允許建立支援的核心物件 虛擬化機制建立新的管理程序物件的 Syscalls 需要 呼叫端可存取管理程序資源,因此元件能 建立虛擬機器可由產品控管。於 也就是必須授予 Fuchsia 元件建立 訪客作業系統,因此產品可以限制 就能充分運用這些功能

CPU 虛擬化

zx_vcpu_create syscall 會建立新的虛擬 CPU (VCPU) 物件和繫結 提供給呼叫執行緒接著,VMM 就能使用 用於讀取及寫入架構的系統呼叫 zx_vcpu_{read|write}_state 註冊該 vCPU。zx_vcpu_enter 系統呼叫是用於造成阻斷的系統呼叫 將內容切換至訪客視窗,而 zx_vcpu_enter 傳回代表 並將結構定義切換回主機也就是沒有執行緒 目前在 zx_vcpu_enter 中,系統不會在 訪客背景資訊。全部zx_vcpu_read_statezx_vcpu_write_statezx_vcpu_enter 必須從呼叫的執行緒呼叫 zx_vcpu_create

zx_vcpu_kick 系統呼叫的存在,是允許主機明確要求 vCPU 會結束,並導致任何對 zx_vcpu_enter 的呼叫傳回。

記憶體與IO 虛擬化

zx_guest_create 系統呼叫會建立新的訪客核心物件。最重要的是 這個系統呼叫會傳回虛擬記憶體位址區域 (vmar) 帳號代碼。VMM 是 可以藉由對應虛擬記憶體,為訪客提供「實體記憶體」 物件 (vmo) 放入這個 vmar由於此 vmar 代表 訪客實際位址空間,此 vmar 的偏移值會對應到 訪客的實際地址。舉例來說,如果 VMM 想要公開 1 GiB 的 訪客實體位址範圍 [0x00000000 - 0x40000000) 的記憶體 (VMM) 就會建立 1 GiB vmo 並對應至訪客實體 vmar,且偏移值為 0。

這個訪客實體 vmar第二層級地址實作 Translation (SLAT),可讓管理程序定義 將主機實體地址 (HPA) 翻譯為訪客實際地址 (GPA)。接著,訪客作業系統就能自行安裝分頁表 可處理從訪客虛擬地址 (GVA) 翻譯成訪客實體 地址。

顯示雙層級地址轉譯的圖表

zx_guest_set_trap 系統呼叫可讓 VMM 安裝 進行裝置模擬訪客可透過以下方式與硬體互動 記憶體對應 I/O (MMIO),包含訪客讀取和 撰寫裝置時,請使用與記憶體相同的指示 存取。若是 MMIO,SLAT 中沒有對應的 的 GPA,將訪客帶進管理程序。

x86 提供另一種處理 IO 裝置的方式,稱為「連接埠對應」 I/O (PIO)。與 PIO 合作時,房客會使用替代指示: 存取裝置,但這些指示仍會導致訪客無法連線 管理程序

繞環處理方式的細節將專屬於 已建立:

ZX_GUEST_TRAP_MEM - 設定 MMIO 的陷阱。讀取或寫入作業 與此陷阱相關聯的訪客實體位址空間內 導致 zx_vcpu_enter 系統呼叫傳回 VMM,如果 負責模擬存取、更新 VCPU 註冊狀態,然後 再次呼叫 zx_vcpu_resume 返回訪客。

ZX_GUEST_TRAP_IO - 與「ZX_GUEST_TRAP_MEM」類似,但不包含設定 將裝設於訪客實體位址空間中的陷阱,將被安裝在 IO 上 處理器的空間如果架構不支援 PIO,這項作業就會失敗。

ZX_GUEST_TRAP_BELL - 設定 MMIO 的非同步陷阱。當訪客寫入 與這個陷阱相關聯的訪客物理位址範圍,而非 zx_vcpu_enter 返回 VMM,管理程序會將 ,並立即重新啟用 vCPU 與此連線相關聯的通訊埠 並在不返回使用者空間的情況下執行。這可用來模擬裝置 是專門用來處理這種模式的舉例來說,Virtio 部裝置允許 訪客驅動程式庫通知虛擬裝置,確認工作運作正常 寫入訪客實體記憶體中的特殊頁面

無法在 IO 空間中設定非同步陷阱。這個外掛程式能讀取具有 不支援「ZX_GUEST_TRAP_BELL」組合。

陷阱處理

VCPU 執行緒通常會花費大部分時間在 zx_vcpu_enter 遭到封鎖。 也就是在訪客背景中執行此 Syscall 的回程 VMM 表示發生錯誤,或是通常發生在 VMM 需要介入才能模擬某些行為。

我們舉幾個具體的例子來說明陷阱 由 VMM 處理。

MMIO 同步陷阱範例

舉例來說,假設 ARM PL011 序列埠模擬。請注意 是 ARM 專用裝置,陷阱處理機制也是如此 支援 ARM 和 x86。

首先,VMM 會註冊同步 MMIO 陷阱 位於 [0x808300000 - 0x808301000) 的房客實際地址範圍內, 向管理程序說明,若存取這個區域,就必須導致 zx_vcpu_enter 即可將控制流程傳回 VMM

接下來,VMM 會在一或多個 vCPU 上呼叫 zx_vcpu_enter 至內容切換 傳入訪客。某個時間點,PL011 驅動程式庫會嘗試從 序列埠控制介面會在 PL011 裝置上註冊 UARTCR。這個 暫存器位於偏移 0x30 中,因此會對應至訪客實體 這個範例中的位址 0x808300030

由於已有訪客實際地址 (0x808300030) 註冊,因此這項讀取作業 客體會帶入 Hypervisor 進行處理。管理程序可以 觀察到這項存取權有相關聯的 ZX_GUEST_TRAP_MEM,且會通過 從 zx_vcpu_enter 傳回控制流程至 VMM,並提供 zx_port_packet_t 內含的陷阱。接著,VMM 就能使用 存取之訪客實際地址,以便將其與對應的 虛擬裝置邏輯。在這種情況下 是維護成員變數中的暫存值

// `relative_addr` is relative to the base address of the trapped region.
zx_status_t Pl011::Read(uint64_t relative_addr, IoValue* value) {
  switch (static_cast<Pl011Register>(relative_addr)) {
    case Pl011Register::CR: {
      std::lock_guard<std::mutex> lock(mutex_);
      value->u16 = control_;
      return ZX_OK;
    }
    // Handle other registers...
  }
}

如此會傳回 16 位元的值,但我們仍需向 。由於邀請對象執行了 MMIO,訪客也預期 產生的結果會是載入指示中指定的任何暫存器。 方法是使用 zx_vcpu_read_statezx_vcpu_write_state 更新目標暫存器值的 sys 呼叫 產生的結果。

顯示同步 MMIO 陷阱的圖表

鐘錶範例

接著,我們示範了鐘塔的運作。在這個範例中 Virtio Device 在主要 VMM 以外的元件中實作。 在初始化期間,VMM 要求 Virtio Device 註冊鈴聲 然後對著陷阱進行運輸, 這樣陷阱將會提交至 Virtio Device 而非 VMMVirtio Device 完成任何設定 陷入負荷,VMM 開始以 zx_vcpu_enter 執行 vCPU,控制流程為 。

訪客的驅動程式庫有時會向訪客實際地址發出 MMIO 寫入 遭 Virtio Device 困住。到時候,客人會切斷 導致系統通知 透過 zx_port_packet_t 傳送至 Virtio Device。值得注意的是 在這種陷阱處理期間,zx_vcpu_enter 一律不會傳回, 管理程序可以快速切換回訪客環境,讓 藉此暫停 vCPU 花費的時間

Virtio Device 收到 zx_port_packet_t 後,就會 例如,處理那個陷阱的裝置這通常涉及讀取和 直接寫入訪客實體記憶體,但進行這項操作時不會 vCPU 執行作業。裝置完成要求後, 使用 zx_vcpu_interrupt 傳送中斷,以便在訪客中驅動程式庫。

由於大多數的通訊都是使用共享記憶體完成,而不是 使用同步陷阱,Virtio 裝置比裝置更有效率 非常仰賴同步陷阱

顯示非同步 MMIO 陷阱的圖表

陷阱處理的架構差異

雖然陷阱的處理技巧都相同,但在此之前 因應陷阱需採取的行動不同 基礎硬體支援最值得注意的是,在 ARM 上,基礎資料會取消 針對硬體產生的部分已解碼資訊 可以轉送至使用者空間的功能 (例如:存取大小、讀取或寫入、目標 註冊等等)。在 Intel 上不會發生這種情形,因此 VMM 必須 執行一些指令解碼以推斷出 可能不準確或不適當

中斷虛擬化功能

Fuchsia 實作部分平台稱之為「分割 irqchip」,模擬 核心中執行的 LAPIC/GICC,並發生 I/OAPIC/GICD 模擬 使用者空間使用者空間 I/OAPIC 和 GICD 向前會中斷到目標 CPU 並透過 zx_vcpu_中斷 syscall 即可

虛擬機器管理員 (VMM)

「Virtual Machine Montior」 (VMM) 是會 透過 syscall 建構及管理虛擬機器 模擬裝置。VMM 會使用 提供給其 GuestConfig FIDL 結構,其中包含 關於哪些裝置應提供給虛擬機器 以及訪客核心、ramdisk 和區塊裝置的資源

整體來說,VMM 會使用管理程序組合虛擬機器 建立訪客和 VCPU 核心物件的 syscall。訪客 RAM 分配 建立一個 VMO,並將其對應至訪客實體記憶體 vmar使用 zx_guest_set_trap 即可註冊虛擬硬體的 MMIO 和 Port-io 處理常式 模擬。VMM 可模擬 PCI 匯流排,並可將裝置連結至該匯流排。這項服務 將訪客核心載入記憶體,並使用各種資源設定啟動資料 例如裝置樹狀結構 blob 或 ACPI 資料表。

記憶體

VMM 會分配 Vmo 做為訪客實體記憶體,並對應此 Vmo 寫入訪客實體記憶體 vmar (由 zx_guest_create 建立)。時間 客串實體記憶體 vmar 中的記憶體 「訪客實際地址」(GPA)。VMM 也會將相同的 Vmo 對應至其 程序位址空間,以便直接存取這個記憶體。時間 呼叫 VMM 的 vmar 中的記憶體,我們將這些位址稱為「Host-Virtual」 地址 (HVA)。VMM 能將 GPA 轉換成 HVA 能夠得知訪客記憶體對應,以及在其本身的 vmar 中取得 就是對應的訪客記憶體

Virtio 裝置與元件

訪客可透過虛擬 I/O 看到許多裝置 (Virtio) 透過 PCI。Virtio 規格定義了一組要支援 經過精心設計,能在虛擬化環境中有效率地執行 以存取訪客實體記憶體,同時將 同步 IO 陷阱為了提升安全性和裝置間的安全性,我們執行 每部 Virtio 裝置都有各自的 Zircon 程序,且只會轉送功能 所需元件例如,只提供 Virtio 封鎖裝置 用於支援虛擬磁碟的特定檔案或裝置的控制代碼,以及 Virtio 主控台只能存取序列串流的 zx::socket。

VMM 與裝置間的通訊是使用 fuchsia.virtualization.hardware FIDL 程式庫。對於每項 裝置時,有一段連結至 VMM 的一小段程式碼,稱為 控制器,扮演這些 FIDL 的用戶端 並連線至實作裝置的元件 設定時間每個裝置執行個體會有一個程序 機器有 3 部 Virtio 區塊裝置,就會有 3 個控制器執行個體和 3 個控制器執行個體 Virtio 3 Zircon 程序封鎖元件。

Virtio 裝置是在運作的共用資料結構概念上運作 訪客實體記憶體。訪客驅動程式庫會分配並初始化這些元件 建構期間的結構,並為 VMM 提供這些結構的指標 訪客實體記憶體。驅動程式庫要通知裝置偵測到該裝置時 對這些結構發布了新工作後,模型會寫入 在訪客實體記憶體中擷取裝置專屬的「通知」頁面,且裝置可以推斷出 追蹤特定事件。每項 裝置元件會註冊此區域的 ZX_GUEST_TRAP_BELL,以便 管理程序可以直接將這些事件轉送至目標元件, 而不必從 VMM 跳出裝置元件就能讀取 並藉由 HVA 讀取這些結構以直接寫入這些結構。

啟動中

VMM 不提供任何訪客 BIOS 或韌體,而是會載入 將訪客資源直接傳入記憶體,並將啟動 vCPU 設為跳躍 直接加入核心進入點詳細步驟會因 載入狀態。

Linux 訪客

對於 x64 Linux 訪客,VMM 會將可開機的核心映像檔 (例如 bzImage) 載入 訪客實體記憶體 (依 Linux 啟動作業標準) 通訊協定,並更新 Real-Mode 核心標頭 和 0 Page 與其他核心資源 (ramdisk、 核心指令列)。VMM 也會產生並載入一組 ACPI 資料表,說明提供給模型的模擬硬體 。

Arm64 Linux 訪客的行為相似,不過我們會按照 arm64 啟動 通訊協定,並提供裝置樹狀結構 blob (DTB) 而非 ACPI 表格

Zircon 訪客

VMM 也支援根據 Zircon 開機程序啟動 Zircon 訪客 Google Cloud 就是最佳選擇這裡提供 Zircon 啟動方式的詳細說明。

邀請對像管理員

訪客管理員元件的作用是封裝訪客二進位檔 (核心、ramdisk、磁碟映像檔) 及配置 (要啟用哪些裝置、 訪客核心設定選項),並在啟動時提供給 VMM

樹狀結構內有 3 間訪客管理員,其中兩個都相當簡單 我們會再介紹一次簡單的邀請對像管理員沒有任何訪客專屬代碼 僅限傳遞至 VMM 的設定和二進位檔。這些邀請對象 然後透過虛擬主控台或虛擬影格緩衝區使用

簡易訪客管理員:ZirconGuestManager DebianGuestManager

更進階的訪客管理員是 TerminaGuestManager, 功能使用透過 Virtio Vsock 執行的 gRPC 服務。 TerminaGuestManager 可以利用額外功能連線到這些服務 並提供更多功能 (在訪客身分中執行指令、掛接檔案系統) 啟動應用程式)。

如要進一步瞭解如何在 Fuchsia 中啟動及使用虛擬化功能,請參閱 開始使用 Fuchsia 虛擬化功能