Android 使用 Linux 核心進行排程、程序隔離、裝置驅動程式、網路和檔案系統管理,但提供自己的原生函式庫、執行階段、框架和應用程式模型。Bionic 是 Android 的 C 函式庫。ART 執行 DEX 位元組碼,而 Binder 提供主要的跨程序 RPC 機制。
執行階段與程序建立 #
建置工具會將 Java 或 Kotlin 原始碼編譯為類別檔案,然後將其轉換為 DEX 程式碼。APK 或應用程式套件的交付拆分會封裝 DEX、資源、原生函式庫、簽署中繼資料和資訊清單。ART 會根據裝置和設定檔狀態適當地編譯或解譯 DEX;APK 並不只是可執行的 JAR。
init 是 Android 的 PID 1 程序。它會掛載早期檔案系統、套用原則、啟動原生服務,以及啟動 Zygote。Zygote 會預先載入常用的執行階段類別和資源,然後依系統要求 fork 應用程式程序。fork 模型會在任一程序寫入頁面之前共用這些頁面,從而降低應用程式啟動成本。
應用程式隔離與 Binder #
安裝套件時通常會指派獨立的 Linux UID。檔案擁有權和核心憑證會隔離應用程式私有檔案,而 SELinux 會對程序、檔案、服務和 Binder 呼叫套用強制存取控制原則。除了核心控制之外,框架和服務邊界也會檢查權限。
在另一個套件中啟動的應用程式元件會在目標套件的程序中執行。Binder 會將交易傳送至該程序,並攜帶呼叫者身分以進行權限檢查。Binder 物件參照是具備生命週期和權限語意的能力;匯出的元件或服務必須驗證所有由呼叫者控制的引數。
系統分割區與更新 #
現代裝置會將作業系統映像檔分割為邏輯分割區,通常為唯讀:
| Mount | Purpose |
|---|---|
/system | 核心框架、執行階段和平台應用程式 |
/system_ext | 具有平台特定生命週期的系統擴充功能 |
/product | 產品和 OEM 自訂內容 |
/vendor | 硬體供應商函式庫、HAL 和設定 |
/odm | 裝置特定的供應商覆蓋層和設定 |
/vendor_dlkm, /system_dlkm | 可動態載入的核心模組 |
/data | 按裝置和使用者區分的可寫入應用程式資料 |
/metadata | 加密和開機服務所需的中繼資料 |
動態分割區會將邏輯分割區置於實體 super 分割區中。dm-5 等 Device-mapper 名稱代表這些邏輯區塊裝置。回報容量接近滿載的唯讀映像檔通常是不變的檔案系統映像檔,並不表示使用者資料儲存空間已耗盡。
Verified Boot 會為開機和已驗證分割區建立信任鏈。A/B 更新會寫入非使用中的插槽,並在驗證後選取該插槽;如果新插槽無法開機,便可復原至先前版本。
APEX 與原生介面 #
APEX 套件會提供選定的低階平台模組,包括 ART 和 Conscrypt。Android 會在開機早期驗證並將 APEX 映像檔掛載至 /apex 下;穩定路徑會公開使用中的版本。供應商介面和硬體抽象層會依照特定 Android 版本的相容性規則,將框架版本與供應商實作分離。
可寫入儲存空間與掛載命名空間 #
/data 是主要的可寫入分割區。檔案型加密會區分裝置加密儲存空間和憑證加密儲存空間:前者在使用者解鎖前即可使用,後者在使用者解鎖後可用。每位使用者的路徑包括 /data/user/0 和 /data/user_de/0。
模擬共用儲存空間會透過 /storage/emulated/0 等路徑公開,並以 /data/media 下的私有儲存空間為後端。FUSE 和掛載命名空間會為每個應用程式和使用者提供適當的檢視,並強制執行範圍儲存空間存取規則。/storage/self/primary 會解析為程序的主要共用儲存空間檢視;程式碼應使用平台儲存空間 API,而不是硬式編碼實作路徑。
proc、sysfs、binderfs、selinuxfs、cgroupfs 和 tracefs 等虛擬檔案系統公開的是核心介面,而不是持久檔案。mount 清單具有裝置、版本和程序命名空間特定性,因此應視為診斷證據,而不是可攜式檔案系統契約。
評論
在 GitHub 上閱讀或評論(發表評論需要登入)