啟動 Fuchsia 模擬器

robots: noindex

ffx emu 指令會在主機上啟動及管理 Fuchsia 模擬器。

概念

Fuchsia 模擬器 (又稱為 FEMU) 提供一種機制,可用於開發及測試 Fuchsia 平台和產品,而不必使用實體硬體裝置。Fuchsia 模擬器是建構在 QEMU 上,這是一個開放原始碼機器模擬器和虛擬化工具。

QEMU 和 AEMU

Fuchsia 模擬器提供兩種模擬引擎:第一個是 Android Emulator (AEMU) 的擴充功能,第二個則是 QEMU 版本 (6.2.0 版)。AEMU 引擎主要用於涉及圖形的工作,因為 AEMU 支援 Vulkan 圖形程式庫。不過,最新的 AEMU (以 QEMU 2.12 分支版本建構) 缺少多個上游修正、功能和效能提升。因此,如果工作流程不需要圖形,建議您在無頭模式下使用 QEMU 引擎。

啟動模擬器時,您必須指定下列資訊:

  • 用於做為後端的引擎。
  • 要模擬的虛擬裝置類型。
  • 要在虛擬裝置上執行的產品。

根據預設,ffx emu 指令會選取 AEMU 引擎,因為大多數工作都需要某種程度的圖形支援。目前,所有現有產品組合都只有單一虛擬裝置類型。

產品組合

FEMU 引擎都會使用一組稱為「產品組合」的 Fuchsia 圖片和中繼資料。使用 Fuchsia SDK 時,您必須事先使用 ffx product download 指令擷取產品套件。產品套件包含不同 CPU 架構的系統映像檔。每個系統映像檔都包含中繼資料 (例如在不同虛擬裝置上執行的硬體規格) 和相關的系統套件。

網路

模擬器與其主機之間有三種網路模式可供選擇:

這些模式會使用 --net 旗標,並分別選取 tapusernone 選項。另外還有 --net auto 模式,如果未指定旗標,則預設為此模式。在 auto 模式中,模擬器會檢查主機上是否有 Tun/Tap 介面,如果有,模擬器會選取 --net tap 模式。不過,如果沒有或 Tun/Tap 介面已忙碌 (例如已附加至其他模擬器程序),模擬器就會選取 --net user 模式。

列出所有可用的產品組合

如要查看線上儲存空間 (預設為 gs://fuchsia 的 Google Cloud Storage) 中所有可用產品組合的清單,請執行下列指令:

ffx --machine json-pretty product list --version <SDK_VERSION>

這個指令會輸出類似以下的輸出內容:

$ ffx --machine json-pretty product list --version 15.20230906.1.1
Progress for "Getting product descriptions"
  development/15.20230906.1.1/product_bundles.json
    1141 of 1141 bytes (100.00%)
[
  {
    "name": "core.vim3",
    "product_version": "15.20230906.1.1",
    "transfer_manifest_url": "gs://fuchsia-public-artifacts-release/builds/8770722574108649889/transfer.json"
  },
  {
    "name": "core.x64",
    "product_version": "15.20230906.1.1",
    "transfer_manifest_url": "gs://fuchsia-public-artifacts-release/builds/8770722574108649873/transfer.json"
  },
  {
    "name": "minimal.x64",
    "product_version": "15.20230906.1.1",
    "transfer_manifest_url": "gs://fuchsia-public-artifacts-release/builds/8770722574108649857/transfer.json"
  },
  {
    "name": "terminal.qemu-arm64",
    "product_version": "15.20230906.1.1",
    "transfer_manifest_url": "gs://fuchsia-public-artifacts-release/builds/8770722574108649841/transfer.json"
  },
  {
    "name": "terminal.x64",
    "product_version": "15.20230906.1.1",
    "transfer_manifest_url": "gs://fuchsia-public-artifacts-release/builds/8770722574108649809/transfer.json"
  }
]

下載產品組合

如要從線上儲存空間 (預設為 gs://fuchsia 的 Google Cloud Storage) 下載產品套件,請執行下列指令:

ffx product download <TRANSFER_MANIFEST_URL> <LOCAL_PATH>

下列範例指令會下載 minimal.x64 產品套件:

$ ffx product download gs://fuchsia-public-artifacts-release/builds/8770722574108649857/transfer.json ~/local_pb --force

這個指令會輸出類似以下的內容:

$ ffx product download gs://fuchsia-public-artifacts-release/builds/8770722574108649857/transfer.json ~/local_pb --force
Progress for "Transfer download"
  complete
    2 of 2 steps (100.00%)

這個指令可能需要幾分鐘才能下載圖片和產品中繼資料。

啟動 Fuchsia 模擬器

如要啟動 Fuchsia 模擬器,請執行下列指令:

ffx emu start PRODUCT_BUNDLE [--name NAME]

PRODUCT_BUNDLE 替換為主機上下載的產品套裝組合路徑。

以下範例指令使用 ~/local_pb 目錄啟動 Fuchsia 模擬器:

$ ffx emu start ~/local_pb

這個指令會輸出類似以下的輸出內容:

$ ffx emu start ~/local_pb
Logging to "/home/alice/.local/share/Fuchsia/ffx/emu/instances/fuchsia-emulator/emulator.log"
Waiting for Fuchsia to start (up to 60 seconds).............................
Emulator is ready.

模擬器啟動後,指令會結束,但模擬器會繼續在背景執行。接著,系統會開啟另一個視窗,並開始顯示輸入產品套件中所含 Fuchsia 系統的圖形介面。

根據預設,Fuchsia 模擬器會以 fuchsia-emulator 的名稱啟動。不過,如要以不同的名稱啟動 Fuchsia 模擬器 (例如在需要啟動多個執行個體時),您可以使用 --name 標記,例如:

$ ffx emu start ~/local_pb --name my-fuchsia-example-01

如要查看所有執行中的模擬器執行個體清單,您可以使用 ffx emu list 指令。

啟動不支援圖形功能的 Fuchsia 模擬器

根據預設,ffx emu start 指令會啟動 Fuchsia 模擬器,並開啟新視窗來顯示模擬器的圖形介面。不過,在某些情況下,您可能會選擇在模擬器例項上停用圖形支援功能,以便執行不需要視覺效果的作業,例如自動化測試。

如要在不顯示圖形的情況下啟動 Fuchsia 模擬器,請執行下列指令:

ffx emu start PRODUCT_BUNDLE --headless [--engine qemu]

PRODUCT_BUNDLE 替換為主機上下載的產品套裝組合路徑。

以下範例指令使用 ~/local_pb 目錄啟動 Fuchsia 模擬器:

$ ffx emu start ~/local_pb --headless --engine qemu

這個指令會輸出類似以下的內容:

$ ffx emu start ~/local_pb --headless --engine qemu
Logging to "/home/alice/.local/share/Fuchsia/ffx/emu/instances/fuchsia-emulator/emulator.log"
Waiting for Fuchsia to start (up to 60 seconds).............................
Emulator is ready.

這個指令會照常在背景啟動 Fuchsia 模擬器的例項,但主機電腦的畫面不會顯示其圖形介面。

列出所有執行中的模擬器例項

如要查看主機上執行中的 Fuchsia 模擬器執行個體清單,請執行下列指令:

ffx emu list

這個指令會輸出類似以下的內容:

$ ffx emu list
[Inactive]  my-fuchsia-example-01
[Active]    fuchsia-emulator

在輸出結果中,每個模擬器執行個體旁邊都會顯示其狀態。如果狀態為 [Active],表示例項正在執行,並能回應其他 Fuchsia 工具。不過,如果狀態為 [Inactive],則表示執行個體已停止執行,但保留工作目錄,或是執行個體仍在執行,但無法回應 (例如因網路故障)。以停用網路功能啟動的執行個體,即使運作正常,也不會顯示為 [Active]

停止模擬器執行個體

如要停止執行中的 Fuchsia 模擬器執行個體,請執行下列指令:

ffx emu stop INSTANCE_NAME

INSTANCE_NAME 替換為執行中的 Fuchsia 模擬器執行個體名稱。

下列範例指令會停止 my-fuchsia-example-01 執行個體:

$ ffx emu stop my-fuchsia-example-01

這個指令會輸出類似以下的輸出內容:

$ ffx emu stop my-fuchsia-example-01
Stopping emulator 'my-fuchsia-example-01'...
Terminating running instance 2752927

這個指令會終止模擬器的執行程序,並移除主機上為該例項建立的臨時工作目錄。(如果您想保留這個工作目錄,請參閱「停止執行中的模擬器執行個體,同時保留其工作目錄」一文。

如果只有一個執行中的模擬器執行個體,您可以省略 INSTANCE_NAME 欄位來停止執行個體,例如:

$ ffx emu stop
Stopping emulator 'fuchsia-emulator'...
Terminating running instance 2752927

如要一次停止所有執行中的例項,您可以使用 --all 標記,例如:

$ ffx emu stop --all
Stopping emulator 'my-fuchsia-example-01'...
Stopping emulator 'fuchsia-emulator'...
Terminating running instance 2749406

停止模擬器執行個體,同時保留其工作目錄

停止執行中的模擬器執行個體時,系統預設會從主機電腦中刪除該執行個體的工作目錄。不過在某些情況下,您可能會想要保留執行個體的工作目錄,以便繼續檢查目錄內容以進行偵錯。

如要在不刪除工作目錄的情況下停止執行中的 Fuchsia 模擬器執行個體,請執行下列指令:

ffx emu stop INSTANCE_NAME --persist

INSTANCE_NAME 替換為執行中的 Fuchsia 模擬器執行個體名稱。

下列範例指令會停止 my-fuchsia-example-01 執行個體:

$ ffx emu stop my-fuchsia-example-01 --persist

這個指令會輸出類似以下的內容:

$ ffx emu stop my-fuchsia-example-01 --persist
Stopping emulator 'my-fuchsia-example-01'...
Terminating running instance 2752927

執行此指令後,執行個體的工作目錄會保留在主機上,而已停止的執行個體會繼續顯示在模擬器執行個體清單 (ffx emu list) 中,並顯示 [Inactive] 狀態。

如要重新啟動這個已停止的模擬器執行個體,請搭配 --reuse 標記執行 ffx emu start 指令,例如:

$ ffx emu start my-fuchsia-example-01 --reuse

當您不再需要工作目錄時,可以再次執行 ffx emu stop 指令來刪除目錄,例如:

$ ffx emu stop my-fuchsia-example-01
Stopping emulator 'my-fuchsia-example-01'...

顯示模擬器設定

如要在主機上查看 Fuchsia 模擬器設定,請執行下列指令:

ffx emu show

這個指令會輸出類似以下的輸出內容:

$ ffx emu show
EmulatorConfiguration {
    device: DeviceConfig {
        audio: AudioDevice {
            model: Hda,
        },
        cpu: VirtualCpu {
            architecture: X64,
            count: 0,
        },
...

以 Tun/Tap 網路模式啟動 Fuchsia 模擬器

--net tap 模式中,主機的核心會設定虛擬網路通道裝置 (請參閱「Tun/Tap」),並將該裝置與主機的實體網路連結。這項設定可讓透過虛擬裝置傳送的流量,轉送至實體網路。模擬器會將其執行個體的虛擬網路介面連結至主機機器上的虛擬通道裝置。這與模擬器例項直接連線至主機的實體網路相同。因此,--net tap 模式可在所有網路選項中提供最快的效能。不過,此模式的設定需要主體機器上的超級使用者存取權 (sudo),且只支援 Linux 主機。

如要在 Tun/Tap 網路模式下啟動模擬器,請執行下列指令:

ffx emu start PRODUCT_BUNDLE --net tap

PRODUCT_BUNDLE 替換為主機上下載的產品套裝組合路徑。

以下範例指令會使用 ~/local_pb 目錄做為產品套件:

$ ffx emu start ~/local_pb --net tap

這個指令會輸出類似以下的內容:

$ ffx emu start ~/local_pb --net tap
Logging to "/home/alice/.local/share/Fuchsia/ffx/emu/instances/fuchsia-emulator/emulator.log"
Waiting for Fuchsia to start (up to 60 seconds)......................
Emulator is ready.

透過 Tun/Tap 網路模式,您可以選擇指定「upscript」來設定網路介面和防火牆例外狀況。這個指令碼會在啟動時執行,適用於使用 Tun/Tap 網路模式執行的每個模擬器執行個體。

如要將網路更新指令碼新增至 ffx 設定,請在啟動模擬器前執行下列指令:

ffx config set emu.upscript <PATH_TO_UPSCRIPT>

PATH_TO_UPSCRIPT 替換為 upscript 檔案的路徑。

以下範例指令會將 my-upscript.sh 新增至 ffx 設定:

$ ffx config set emu.upscript /home/alice/my-fuchsia-project/my-upscript.sh

以使用者網路模式啟動 Fuchsia 模擬器

如果您在主機上沒有超級使用者存取權 (sudo),可以使用 --net user 模式設定網路。在這個模式下,模擬器會透過 SLiRP 做為防火牆運作。模擬器執行個體的傳出流量沒有任何限制。不過,傳送流量至模擬器執行個體需要進行以下設定:

  • 虛擬裝置的規格是產品套件 (例如 ~/local_pb) 的一部分,會預先定義裝置所需的連接埠對應項目。
  • 這些通訊埠可以在啟動模擬器執行個體時,對應至主機上的未使用通訊埠。

舉例來說,如要設定主機與模擬器執行個體之間的 SSH 連線,首先產品套件的虛擬裝置規格必須允許裝置使用執行個體的 SSH 連接埠 (通常為 22)。接著,啟動 Fuchsia 模擬器時,您可以使用 ffx emu start 指令將執行個體的 SSH 通訊埠對應至主機上未使用的通訊埠,例如 8022。模擬器執行個體開始執行後,您就可以透過主機機器的 8022 通訊埠,建立與執行個體的 SSH 工作階段。

在虛擬裝置規格中,ports 欄位會提供服務名稱和通訊埠號碼清單,例如:

ports = {
        ssh = 22
        mdns = 5353
        debug = 2345
}

上例表示模擬器必須在啟動期間,將模擬器執行個體的三個指定通訊埠 (即 22、5353 和 2345) 對應至主機上的未使用通訊埠。根據這個規格,模擬器會分別使用 sshmdnsdebug 做為三個通訊埠的名稱。針對每個通訊埠,您可以使用 --port-map 標記將名稱對應至主機電腦上未使用的通訊埠,例如:

$ ffx emu start ~/local_pb --net user --port-map ssh:8022 --port-map debug:12345

虛擬裝置規格中未明確使用 --port-map 標記對應的任何通訊埠,都會在啟動期間任意指派至主機上未使用的通訊埠。最終的連接埠對應可在 ffx emu show 的輸出內容中看到。

如要在使用者網路模式下啟動模擬器,請執行下列指令:

ffx emu start PRODUCT_BUNDLE --net user [--port-map PORT_NAME:PORT_NUMBER]

更改下列內容:

  • PRODUCT_BUNDLE:主機上下載的產品套裝組合路徑。
  • PORT_NAME – (選用) 模擬器執行個體上的服務名稱。
  • PORT_NUMBER:(選用) 您要對應 PORT_NAME 服務目標的主體機器通訊埠編號。

下方的範例指令會在使用者網路模式下啟動模擬器:

$ ffx emu start ~/local_pb --net user

如果未指定 --port-map 標記,模擬器會將模擬器執行個體上的服務對應至主機上的任何未使用的通訊埠。

以下範例指令會在使用者網路模式下啟動模擬器時,指定通訊埠對應項目:

$ ffx emu start ~/local_pb --net user --port-map ssh:8022 --port-map debug:12345

如要瞭解使用者網路模式中模擬器執行個體的通訊埠對應方式,請執行 ffx emu show 並檢查輸出內容的 port_map 欄位,例如:

$ ffx emu show
EmulatorConfiguration {
    [...]
    host: HostConfig {
        [...]
        networking: User,
        port_map: {
            "ssh": PortMapping {
                guest: 22,
                host: Some(
                    8022,
                ),
            },
            "mdns": PortMapping {
                guest: 5353,
                host: Some(
                    35801,
                ),
            },
            "debug": PortMapping {
                guest: 2345,
                host: Some(
                    12345,
                ),
            },
        },
    },
    [...]
}

啟動已停用網路功能的 Fuchsia 模擬器

指定 --net none 時,與虛擬機器上並未安裝網路卡一樣,模擬器執行個體無法存取網路功能。與模擬器執行個體通訊的唯一方法,就是透過 QEMU 監控器和模擬序列埠

如要啟動網路已停用的模擬器,請執行下列指令:

ffx emu start PRODUCT_BUNDLE --net none [--console]

PRODUCT_BUNDLE 替換為主機上下載的產品套裝組合路徑。

這個指令會輸出類似以下的內容:

$ ffx emu start ~/local_pb --net none
Logging to "/home/alice/.local/share/Fuchsia/ffx/emu/instances/fuchsia-emulator/emulator.log"
Waiting for Fuchsia to start (up to 60 seconds).............................................................
Emulator did not respond to a health check before timing out.

網路功能停用時,ffx emu start 指令無法完成執行個體的「健康狀態檢查」,導致執行個體狀態為 [Inactive],這也是預期的結果,例如:

$ ffx emu list
[Inactive]    fuchsia-emulator

啟動 Fuchsia 模擬器,並使用主控台進行偵錯

Fuchsia 模擬器提供下列內建主控台,方便開發人員與模擬器例項互動:

這兩個控制台都支援 QEMU 和 AEMU 引擎。

QEMU 監控器

使用 QEMU 顯示器,您可以直接向模擬器程序發出指令。其中部分指令可讓您修改模擬裝置、查詢虛擬硬體狀態,以及使用虛擬硬體信號終止模擬器程序。(如要進一步瞭解可用的指令,請參閱 QEMU Monitor 頁面)。

如要啟動連接至 QEMU 監控器的模擬器執行個體,請執行下列指令:

ffx emu start PRODUCT_BUNDLE --monitor

PRODUCT_BUNDLE 替換為主機上下載的產品套裝組合路徑。

以下範例指令使用 ~/local_pb 產品套件:

$ ffx emu start ~/local_pb --monitor

這個指令會輸出類似以下的內容:

$ ffx emu start ~/local_pb --monitor
QEMU 2.12.0 monitor - type 'help' for more information
(qemu)

當您在執行附加 QEMU 監視器的模擬器執行個體時,指令不會立即退出至終端機。而是會將您帶入 QEMU 監控提示

如要退出 QEMU 監控器提示,您可以發出 quit 指令,這也會終止模擬器執行個體,例如:

$ ffx emu start ~/local_pb --monitor
QEMU 2.12.0 monitor - type 'help' for more information
(qemu) quit

WARNING | Write called without a backing file!
$

Fuchsia 模擬的序列埠

如果模擬器執行個體在連結至模擬序列埠時啟動,Fuchsia 平台會將序列埠視為終端機。在開機程序期間,這個終端機會透過通訊埠串流核心記錄,系統開機後,就會顯示 Fuchsia 指令列提示。

如要啟動連接至模擬序列埠的模擬器執行個體,請執行下列指令:

ffx emu start PRODUCT_BUNDLE --console

PRODUCT_BUNDLE 替換為主機上下載的產品套裝組合路徑。

以下範例指令使用 ~/local_pb 產品套件:

$ ffx emu start ~/local_pb --console

這個指令會輸出類似以下的內容:

alice@alice:~$ ffx emu start ~/local_pb --console
INFO    | Android emulator version 31.3.8.0 (build_id 8611574) (CL:N/A)
[... various log entries]
[00021.699] 01095:01158> [component_manager] INFO: Connecting fuchsia.sys2.LifecycleController
$

啟動模擬器執行個體之後,這個指令會將您帶入 Fuchsia 指令列提示中,方便您將各種裝置端指令列直接發送至執行個體。

如要結束序列埠主控台,您可以發出 dm poweroff 指令,這個指令也會終止模擬器執行個體,例如:

$ dm poweroff
[00258.335] 26935:26939> [shutdown-shim]: checking power_manager liveness
[... various log entries]
[00260.447] 03742:03744> [00260.447038][3742][3744][driver_manager.cm] WARNING: [src/devices/bin/driver_manager/v1/suspend_handler.cc(211)] Failed to cause VFS exit ourselves, this is expected during orderly shutdown: FIDL operation failed d
[00260.429] 03341:03344> WARNING | Write called without a backing file!
alice@alice:~$