自 2025 年 3 月 27 日起,我們建議您使用 android-latest-release
而非 aosp-main
建構及貢獻 AOSP。詳情請參閱「Android 開放原始碼計畫變更」。
Microdroid
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
Microdroid 是執行在 pVM 中的迷你 Android 作業系統。您不必使用 Microdroid,也可以使用任何作業系統啟動 VM。不過,pVM 的主要用途並非執行獨立的作業系統,而是提供隔離的執行環境,用於執行應用程式的部分內容,並提供比 Android 更強的機密性和完整性保證。
在傳統作業系統中,要提供強大的機密性和完整性,需要進行大量 (通常是重複) 的工作,因為傳統作業系統不符合整體 Android 架構。舉例來說,在標準 Android 架構中,開發人員需要實作一種方法,以便在 pVM 中安全地載入及執行部分應用程式,而酬載則是根據 glibc 建構。Android 應用程式使用 Bionic,通訊需要透過 vsock 使用自訂協定,使用 ADB 進行偵錯相當困難。
Microdroid 提供現成的作業系統映像檔,可讓開發人員以最少的力氣將應用程式的一部分卸載至 pVM,以填補這些空白。原生程式碼是針對 Bionic 建構,通訊會透過 Binder 進行,且允許從 Android 主機匯入 APEX,並公開 Android API 的子集,例如使用硬體支援金鑰的加密運算的 KeyStore。總體而言,開發人員應該會發現 Microdroid 是個熟悉的環境,因為他們已習慣在完整的 Android 作業系統中使用這些工具。
功能
Microdroid 是精簡版 Android,其中包含一些專屬於 pVM 的額外元件。Microdroid 支援:
- NDK API 的子集 (提供 Android 實作 libc 和 Bionic 的所有 API)
- 偵錯功能,例如 ADB、Logcat、Tombstone 和 gdb
- 驗證開機程序和 SELinux
- 載入及執行嵌入 APK 的二進位檔和共用程式庫
- 透過 vsock 進行 Binder RPC,並透過隱含完整性檢查交換檔案
- 載入 APEX
Microdroid 不支援以下項目:
Microdroid 架構
Microdroid 與 Cuttlefish 相似,兩者都具有與標準 Android 相似的架構。Microdroid 包含下列分區映像檔,這些映像檔會在複合磁碟映像檔中分組:
bootloader
:驗證並啟動核心。
boot.img
:包含核心和初始化 RAM 磁碟。
vendor_boot.img
:包含 VM 專屬的核心模組,例如 virtio。
super.img
:包含系統和供應商邏輯磁碟分割區。
vbmeta.img
:包含驗證開機程序中繼資料。
分割區映像檔會在 Virtualization APEX 中出貨,並由 VirtualizationService
封裝為複合磁碟映像檔。除了主要 OS 組合磁碟映像檔外,VirtualizationService
還負責建立下列其他分割區:
payload
- 由 Android 的 APEX 和 APK 支援的一組分割區
instance
:用於保存每個執行個體已驗證的啟動資料 (例如每個執行個體的鹽值、信任的 APEX 公開金鑰和復原計數器) 的加密分割區
開機順序
Microdroid 啟動序列會在裝置啟動後發生。請參閱「架構」文件中的「pVM 韌體」一節,瞭解裝置啟動程序。圖 1 顯示 Microdroid 啟動序列期間執行的步驟:
圖 1. MicroDroid 執行個體的安全啟動流程
以下說明這些步驟:
系統會透過 crosvm 將引導程式載入記憶體,並開始執行 pvmfw。在跳轉至啟動載入程式之前,pvmfw 會執行兩項工作:
- 驗證啟動載入器,檢查是否來自可信任的來源 (Google 或 OEM)。
- 透過使用執行個體映像檔,確保在同一個 pVM 的多個啟動作業中,一律使用相同的啟動載入程式。具體來說,pVM 最初會使用空白的執行個體映像檔啟動。pvmfw 會在執行個體映像檔中儲存啟動載入程式的身分,並對其進行加密。因此,下次以相同執行個體映像檔啟動 pVM 時,pvmfw 會從執行個體映像檔解密已儲存的 ID,並驗證該 ID 是否與先前儲存的 ID 相同。如果身分不同,pvmfw 就會拒絕啟動。
接著,啟動載入程式會啟動 Microdroid。
開機載入程式會存取執行個體磁碟。與 pvmfw 類似,開機載入程式也有執行個體磁碟機,其中包含先前開機時在這個執行個體中使用的分割區映像檔資訊,包括公開金鑰。
啟動載入程式會驗證 vbmeta 和鏈結分區 (例如 boot
和 super
),如果驗證成功,就會衍生下階段的 pVM 機密資料。接著,Microdroid 會將控制權交給核心。
由於超級分區已由引導程式驗證 (步驟 3),核心會無條件掛載超級分區。與完整的 Android 一樣,超級分區由多個邏輯分區組成,這些分區會掛載在 dm-verity 上。接著,控制權會傳遞至 init
程序,啟動各種原生服務。init.rc
指令碼與完整 Android 指令碼類似,但會根據 Microdroid 的需求進行調整。
init
程序會啟動 Microdroid 管理工具,該工具會存取例項映像檔。Microdroid 管理員服務會使用從前一個階段傳遞的金鑰解密映像檔,並讀取這個 pVM 信任的用戶端 APK 和 APEX 的公開金鑰和復原計數器。zipfuse
和 apexd
分別掛載用戶端 APK 和要求的 APEX 時,會在稍後使用這項資訊。
Microdroid 管理員服務會啟動 apexd
。
apexd
會在 /apex/<name>
目錄中掛接 APEX。Android 和 Microdroid 掛載 APEX 的方式唯一的差異在於,在 Microdroid 中,APEX 檔案來自虛擬區塊裝置 (/dev/vdc1
、…),而非一般檔案 (/system/apex/*.apex
)。
zipfuse
是 Microdroid 的 FUSE 檔案系統。zipfuse
會掛接用戶端 APK,而 APK 本質上是做為檔案系統的 ZIP 檔案。在底下,APK 檔案會以虛擬區塊裝置的形式,由使用 dm-verity 的 pVM 傳遞,這與 APEX 相同。APK 包含設定檔,其中列出應用程式開發人員為此 pVM 例項要求的 APEX 清單。apexd
會在啟用 APEX 時使用這份清單。
啟動流程會傳回至 Microdroid 管理員服務。接著,管理員服務會使用 Binder RPC 與 Android 的 VirtualizationService
通訊,以便回報當機或關機等重要事件,並接受終止 pVM 等要求。管理服務會從 APK 的設定檔讀取主要二進位檔的位置,然後執行該檔案。
檔案交換 (AuthFS)
Android 元件通常會使用檔案做為輸入、輸出和狀態,並將這些檔案傳遞為檔案描述項 (AIDL 中的 ParcelFileDescriptor
類型),並由 Android 核心控制存取權。AuthFS 可提供類似的功能,在跨 pVM 邊界、彼此不信任的端點之間交換檔案。
從根本上來說,AuthFS 是遠端檔案系統,可針對個別存取作業執行透明完整性檢查,類似於 fs-verity
。這些檢查可讓前端 (例如在 pVM 中執行的檔案讀取程式) 偵測不受信任的後端 (通常是 Android) 是否竄改檔案內容。
如要交換檔案,後端 (fd\_server
) 會啟動每個檔案設定,指定檔案是用於輸入 (唯讀) 還是輸出 (讀寫)。針對輸入內容,前端會強制要求內容與 Merkle 樹狀結構中的已知雜湊相符,以便進行存取時驗證。針對輸出內容,AuthFS 會在內部維護寫入作業觀察到的內容雜湊樹狀圖,並可在讀取資料時強制執行完整性。
目前的基礎傳輸機制是以 Binder RPC 為基礎,但日後可能會變更,以便提升效能。
金鑰管理
pVM 會提供穩定的封條印記金鑰,可用於保護持續性資料,以及認證金鑰,可用於產生可由 pVM 驗證的簽章。
Binder RPC
大多數 Android 介面都是以 AIDL 表示,而 AIDL 是建構在 Binder Linux 核心驅動程式之上。為了支援 pVM 之間的介面,Binder 通訊協定已重新編寫,以便透過 Socket 運作,在 pVM 的情況下為 vsock。透過 Socket 運作可讓 Android 現有的 AIDL 介面在這個新環境中使用。
如要設定連線,一個端點 (例如 pVM 酬載) 會建立 RpcServer
物件、註冊根物件,並開始監聽新的連線。用戶端可以使用 RpcSession
物件連線至此伺服器,取得 Binder
物件,然後如同使用核心繫結器驅動程式中的 Binder
物件一樣使用該物件。
這個頁面中的內容和程式碼範例均受《內容授權》中的授權所規範。Java 與 OpenJDK 是 Oracle 和/或其關係企業的商標或註冊商標。
上次更新時間:2025-07-27 (世界標準時間)。
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["缺少我需要的資訊","missingTheInformationINeed","thumb-down"],["過於複雜/步驟過多","tooComplicatedTooManySteps","thumb-down"],["過時","outOfDate","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["示例/程式碼問題","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-07-27 (世界標準時間)。"],[],[],null,["# Microdroid is a mini-Android OS that runs in a pVM. You don't have to use\nMicrodroid, you can start a VM with any OS. However, the primary use cases\nfor pVMs aren't running a standalone OS but rather offering an isolated\nexecution environment for running a portion of an app with stronger\nconfidentiality and integrity guarantees than Android can provide.\n\nWith traditional operating systems, providing strong confidentiality and\nintegrity requires a fair amount of work (often duplicated)\nbecause traditional operating systems don't fit with the overarching Android\narchitecture. For example, with the standard Android architecture, developers\nneed to implement a means of securely loading and executing part of their app\nin the pVM, and the payload is built against glibc. The Android app uses\nBionic, communication requires a custom protocol over vsock, and debugging using\nadb is challenging.\n\nMicrodroid fills these gaps by providing an off-the-shelf OS image designed to\nrequire the least amount of effort from developers to offload a portion of\ntheir app into a pVM. Native code is built against Bionic, communication happens\nover Binder, and it allows importing APEXes from the host Android and exposes\na subset of the Android API, such as keystore for cryptographic operations with\nhardware-backed keys. Overall, developers should find Microdroid a familiar\nenvironment with the tools they've grown accustomed in the full Android OS.\n\nFeatures\n--------\n\nMicrodroid is a stripped down version of Android with a few additional\ncomponents specific to pVMs. Microdroid supports:\n\n- A subset of NDK APIs (all APIs for Android's implementation of libc and Bionic are provided)\n- Debugging features, such as adb, logcat, tombstone, and gdb\n- Verified Boot and SELinux\n- Loading and executing a binary, together with shared libraries, embedded in an APK\n- Binder RPC over vsock and exchange of files with implicit integrity checks\n- Loading of APEXes\n\nMicrodroid doesn't support:\n\n- Android Java APIs in the `android.\\*` packages\n\n | **Note:** Core Java APIs in the `java.\\*` packages can be supported by activating the ART APEX in the VM.\n- SystemServer and Zygote\n\n- Graphics/UI\n\n- HALs\n\nMicrodroid architecture\n-----------------------\n\nMicrodroid is similar to\n[Cuttlefish](/docs/devices/cuttlefish) in that both have an architecture that's\nsimilar to standard Android. Microdroid consists of the following partition\nimages grouped together in a composite disk image:\n\n- `bootloader` - Verifies and starts the kernel.\n- `boot.img` - Contains the kernel and init ramdisk.\n- `vendor_boot.img` - Contains VM-specific kernel modules, such as virtio.\n- `super.img` - Consists of system and vendor logical partitions.\n- `vbmeta.img` - Contains verified boot metadata.\n\nThe partition images ship in the Virtualization APEX and are packaged in\na composite disk image by `VirtualizationService`. In addition to the main\nOS composite disk image, `VirtualizationService` is responsible for creating\nthese other partitions:\n\n- `payload` - A set of partitions backed by Android's APEXes and APKs\n- `instance` - An encrypted partition for persisting per-instance verified boot data, such as per-instance salt, trusted APEX public keys, and rollback counters\n\nBoot sequence\n-------------\n\nThe Microdroid boot sequence occurs after\n[Device boot](/docs/core/virtualization/architecture#device-boot). Device boot is\ndiscussed in the pVM Firmware section of the [Architecture](/docs/core/virtualization/architecture)\ndocument. Figure 1 shows the steps that take place during the Microdroid boot\nsequence:\n\n\n**Figure 1.** Secure bootflow of microdroid instance\n\n\u003cbr /\u003e\n\nHere's an explanation of the steps:\n\n1. The bootloader is loaded into memory by crosvm and pvmfw starts\n executing. Before jumping to the bootloader, pvmfw performs two tasks:\n\n - Verifies the bootloader to check if it is from a trusted source (Google or an OEM).\n - Ensures that the same bootloader is used consistently across multiple boots of the same pVM through the use of the instance image. Specifically, the pVM is initially booted with an empty instance image. pvmfw stores the identity of the bootloader in the instance image and encrypts it. So, the next time the pVM is booted with the same instance image, pvmfw decrypts the saved identity from the instance image and verifies that it's the same that was previously saved. If the identities differ, pvmfw refuses to boot.\n\n The bootloader then boots Microdroid.\n2. The bootloader accesses the instance disk. Similar to pvmfw, the\n bootloader has an instance disk drive with information about partition images\n used in this instance during previous boots, including the public key.\n\n3. The bootloader verifies vbmeta and the chained partitions, such as `boot`\n and `super`, and, if successful, derives the next-stage pVM secrets.\n Then, Microdroid hands control over to the kernel.\n\n4. Because the super partition has already been verified by the bootloader\n (step 3), the kernel unconditionally mounts the super partition. As with the\n full Android, the super partition consists of multiple logical partitions\n mounted over dm-verity. Control is then passed to the `init` process, which\n starts various native services. The `init.rc` script is similar to that of full\n Android but tailored to the needs of Microdroid.\n\n5. The `init` process starts the Microdroid manager, which accesses the instance\n image. The Microdroid manager service decrypts the image using the key passed\n from the previous stage and reads the public keys and rollback counters of the\n client APK and APEXes that this pVM trusts. This information is used later by\n `zipfuse` and `apexd` when they mount the client APK and requested APEXes,\n respectively.\n\n6. The Microdroid manager service starts `apexd`.\n\n7. `apexd` mounts the APEXes at `/apex/\u003cname\u003e` directories. The only difference\n between how Android and Microdroid mount APEXes is that in\n Microdroid, the APEX files are coming from virtual block devices\n (`/dev/vdc1`, ...), not from regular files (`/system/apex/*.apex`).\n\n8. `zipfuse` is Microdroid's FUSE file system. `zipfuse` mounts the client APK,\n which is essentially a Zip file as a file system. Underneath, the APK file is\n passed as a virtual block device by the pVM with dm-verity, same as APEX. The\n APK contains a config file with a list of APEXes that the app developer has\n requested for this pVM instance. The list is used by `apexd` when activating\n APEXes.\n\n9. The boot flow returns to the Microdroid manager service. The manager\n service then communicates with Android's `VirtualizationService` using\n Binder RPC so that it can report important events like crash or shutdown,\n and accept requests such as terminating the pVM. The manager service reads the\n location of the main binary from the APK's config file and executes it.\n\nFile exchange (AuthFS)\n----------------------\n\nIt's common for Android components to use files for input, output, and state\nand to pass these around as file descriptors (`ParcelFileDescriptor` type in\nAIDL) with access controlled by the Android kernel. AuthFS facilitates similar\nfunctionality for exchanging files between mutually distrusting endpoints\nacross pVM boundaries.\n\nFundamentally, AuthFS is a remote file system with transparent integrity checks\non individual access operations, similar to `fs-verity`. The checks allow the\nfrontend, such as a file-reading program running in a pVM, to detect if the\nuntrusted backend, typically Android, tampered with file content.\n\nTo exchange files, the backend (`fd\\_server`) is started with per-file\nconfiguration specifying whether it's meant for input (read-only) or output\n(read-write). For input, the frontend enforces that the contents match a known\nhash, on top of a Merkle tree for on-access verification. For output, AuthFS\ninternally maintains a hash tree of the contents as observed from write\noperations and can enforce integrity when the data are read back.\n\nThe underlying transport is currently based on Binder RPC, however that might\nchange in the future to optimize performance.\n\nKey management\n--------------\n\npVMs are provided with a stable *sealing key* that's suitable for protecting\npersistent data, and an *attestation key* that's suitable for producing\nsignatures that are verifiably produced by the pVM.\n\nBinder RPC\n----------\n\nA majority of Android's interfaces are expressed in\n[AIDL](https://developer.android.com/guide/components/aidl), which\nis built on top of the Binder Linux kernel driver. To support interfaces\nbetween pVMs, the Binder protocol has been rewritten to work over sockets,\n[vsock](/docs/core/virtualization/virtualization-service#vm-sockets)\nin the case of pVMs. Operating over sockets allows Android's existing AIDL\ninterfaces to be used in this new environment.\n\nTo set up the connection, one endpoint, such as pVM payload, creates\nan `RpcServer` object, registers a root object, and begins listening for new\nconnections. Clients can connect to this server using an `RpcSession` object,\nget the `Binder` object, and use it exactly like a `Binder` object is used\nwith the kernel Binder driver."]]