本文件說明 Sysmem 的 VMO 階層 管理記憶體的方式本文假設您對 記憶體和非 Symem 記憶體的計算 在 Fuchsia 的幫助下。
堆積
系統會從堆積分配所有 VMO。目前的堆積如下:
名稱 | 固定集區 | 說明 |
---|---|---|
合成核心 | 否 | 一般主記憶體 |
SysmemAmlogicProtectedPool | 是 | 無法從 CPU 存取記憶體 |
SysmemContiguousPool | 是 | 實體連續的主記憶體 |
tee_secure | 是 | 特殊用途的受保護記憶體 (適用於 Amlogic 解密編碼影片) |
Sysmem-external-heap (可能多個) | 否 | 目前用於 goldfish |
合成孔雀 | 否 | 連續的主記憶體;只會在沒有 SysmemContiguousPool 的系統上使用 |
並非所有堆積都會從固定集區分配;例如:「核心」以及「Contig Core」
因此能從主要記憶體分配資源某些堆積會直接與
fuchsia.sysmem.HeapType 值,但所選的堆積也可能
取決於 is_physically_contiguous
等 BufferMemorySettings 成員。
合成核心
從主記憶體分配的 Sysmem-core。如果沒有 在記憶體中加入限制
SysmemContiguousPool
系統中的 CPU 和部分其他裝置只需要虛擬連續的 記憶體用量他們可以挑選任何實際地址的網頁, 透過 MMU 硬體指派新的連續虛擬位址。這樣一來 分配記憶體,因為任何實體頁面都可以使用
但部分硬體不支援 MMU 或零散收集能力。沒錯 硬體需要實體連續的位址空間 都會以相同順序在 RAM 中運作系統執行時,主記憶體 變得零碎,變得不可能 以便找出可用記憶體長時間運作的情形 因為其他分配的頁面 在記憶體周圍隨機配置
為了避免發生這個問題,Sysmem 擁有獨立的連續集區。這項服務 會在啟動後不久就分配大量記憶體 分段完成,然後將較小的區段分派給應用程式。理論上 就算記憶體有限,但實際上能發揮效果,因為 系統會從集區分配更大的記憶體區塊,而 多個區塊會同時釋放回集區。
SysmemAmlogicProtectedPool
在搭載 Amlogic SoC 的系統上,必須採用 DRM (受保護記憶體) 影片 配置到特殊區域,方便存取權控管機制 無法讀取已解密的影片。這些區域必須由 且僅供 GPU 和其他硬體在 硬體,確保硬體不會洩漏記憶體
記憶體不能標示為受保護或不受任意保護。硬體 只能將少數 (小於 32) 區域標示為受保護。為了支援這項功能 sysmem 可以在啟動後立即分配受保護的集區 (類似 並指示韌體保護其中所有的記憶體 區域。然後再從這個受保護的記憶體集區中分派。
tee_secure
tee_secure 是另一種受保護的記憶體類型,而記憶體的 資料類型。韌體會分配這個區域 ZBI 必須告訴 zircon 不會從記憶體中配置,也不會碰觸到記憶體。其他驅動程式庫 可以擷取記憶體和來自 韌體更新,然後告訴 sysmem。Sysmem 可以從這個堆積分量來分配 。
Sysmem-外部堆積
外部堆積不一定使用真實的記憶體。例如:金魚 堆積是外部堆積,代表 FEMU 以外的影片記憶體 虛擬機器用戶端可以傳遞 VMO 控制代碼,但 直接寫入記憶體;相反地,金魚驅動程式庫看著主持人 使用 VMOkoid 設定資源
VMO 階層
Sysmem 採用 VMO 階層結構 用戶端。有三種方式可讓 VMO 保持運作:
VMO 的控制代碼。
將 VMO 對應至程序位址空間。
PMT 表示對應至裝置。
基於安全考量,sysmem 無法收回 VMO 要用於 直到這類型的參照都消失為止適用一般裝置 VMO 是核心,核心只會在所有參照項目後刪除 VMO 才能處理這個問題 逐漸消失。不過,sysmem 會從較大的實體位址分配 VMO 因此需要深入分析 VMO 是否已刪除 決定要重複使用的記憶體範圍
核心支援 ZX_VMO_ZERO_CHILDREN
信號,協助您完成上述操作
用途 - 如果 VMO 的所有子項都關閉,
系統會在父項 VMO 上發出 ZX_VMO_ZERO_CHILDREN
信號。
用戶端分葉 VMO
這些是發送給用戶端的 VMO請呼叫
BufferCollection.SetName,然後才分配 VMO。客戶
也可以直接在 VMO 上設定 ZX_PROP_NAME
,但不建議使用
因為 sysmem 驅動程式庫無法存取該名稱
Sysmem 也會保留參照這些 VMO, 即使目前沒有子項,BufferCollection 仍會繼續參照這些變數 VMO 控制代碼
中等 VMO
每個分葉 VMO 都會有一個中間的 VMO 做為父項。對應項目之間有 1-1 的對應關係 以及中間的 VMO這些名稱由堆積設定,且通常為固定 所有來自堆積的 VMO以 SysmemContiguousPool-child 為例 連續集區中的 VMO。
Sysmem 使用這些 VMO 偵測是否已清除分葉 VMO 的所有參考資料 ;收到 ZX_VMO_ZERO_CHILDREN 後就會知道 即可刪除 VMO,或許還可以重複使用聊天室中等 VMO 永遠 會在 sysmem 程序之外傳遞,因此用戶端不會參照這些憑證
堆積 VMO
這些節點代表堆積中 VMO 所分配的整個記憶體集區 它們通常會在啟動後不久就分配,以確保有足夠的記憶體 可以使用。堆積 VMO 可能代表 位址 - 例如 tee_secure 疊加特定的實體範圍 由系統啟動載入程式所分配的
中等 VMO 會做為堆積 Vmo 的「配量」分配, 每個中間 VMO 代表堆積中不同範圍的記憶體
如果堆積不代表記憶體的實體集區,就不需要 堆積 VMO在這種情況下,系統會在沒有父項 VMO 的情況下分配中等 VMO。
正在回報記憶體
檢查
Sysmem 提供「Inspect」階層,回報其記憶體用量 快照以及其他用戶端應用程式以下提供簡單的階層範例:
root:
sysmem:
collections:
logical-collection-0:
allocator_id = 1
heap = 0
min_coded_height = 1024
min_coded_width = 600
name = vc-framebuffer
pixel_format = 101
pixel_format_modifier = 0
size_bytes = 2490368
vmo_count = 1
collection-5:
channel_koid = 20048
debug_id = 5498
debug_name = driver_host
collection-6:
channel_koid = 20050
debug_id = 5498
debug_name = driver_host
collection-at-allocation-7:
debug_id = 19829
debug_name = virtual-console.cm
min_buffer_count = 1
collection-at-allocation-8:
debug_id = 5498
debug_name = driver_host
collection-at-allocation-9:
debug_id = 5498
debug_name = driver_host
vmo-20085:
koid = 20085
heaps:
SysmemContiguousPool:
allocations_failed = 0
allocations_failed_fragmentation = 0
free_at_high_water_mark = 37498880
high_water_mark = 2490368
id = 1
is_ready = true
last_allocation_failed_timestamp_ns = 0
max_free_at_high_water = 37498880
size = 39989248
used_size = 2490368
vmo-20085:
koid = 20085
size = 2490368
SysmemRamMemoryAllocator:
id = 0
Sysmem 透過
/dev/diagnostics/class/sysmem/XXX.inspect
檔案 (其中 XXX 是偽隨機)
3 位數的 ID)。每個顯示的邏輯集合都代表一組相同的
以及由一組用戶端分配的緩衝區。這些邏輯集合包含清單
中小型社團系列作品中,幼兒專用的
系統的生命週期,可用於識別作業中的 sysmem VMO
。
所有堆積也都有檢查節點。這些屬性包括 並查看所有子 VMO 因此無法進行任何分配有些堆積只有名稱和 ID 屬性 而不是從 VM 分配到的 VMO 相關資訊
邏輯集合的 allocator_id
與所用堆積的 id
相符
來分配記憶體
由於 sysmem 並沒有檢視資料,因此檢查資料有限 系統中的處理程序例如會不知道 也保留了對其 VMO 的參照,但至少只有一項程序。 也無法得知建立 VMO 的用戶端程序確切名稱。 Sysmem 用戶端應使用其呼叫 Allocator.SetDebugClientInfo 程序名稱和 koid 參數,但這並非強制規定, 用戶端集的名稱正確
然而,有些資訊
從檢查資料擷取出來舉例來說,用戶端程序可以留存於某個管道
對 BufferCollection 的控制,不會保留任何對 VMO 的控制代碼。僅限
sysmem 知道 BufferCollection 管道與內部 VMO 之間的對應
整個過程。channel_koid
屬性提供伺服器的資訊
感謝所有管道。
ZX_INFO_PROCESS_VMOs
這個系統呼叫可供 memgraph
和 mem
工具使用。判斷
程序包含 VMO 的參照,這是歸因記憶體的重要方式
以安全的方式處理資料
sysmem 使用的 VMO 階層可能會導致這些工具發生問題。適用對象
例如,mem
會忽略沒有任何修訂的 VMO
記憶體 (已分配記憶體,搭配實體記憶體) 以避免雜亂
輸出內容這會導致我忽略分葉 VMO,因為這個 VM 是
實際分配記憶體的樹狀結構阿姆有一些駭客入侵。
會將記憶體資訊向下向下
SysmemContiguousPool
和SysmemAmlogicProtectedPool
- 會檢查
「size」並假設系統分配了所有記憶體。這個
僅適用於分配至無重疊的固定大小集區
為何只能使用硬式編碼的集區。
外部堆積 VMO 實際上不會 訪客虛擬機器中的記憶體容量。因此,我負責 以不報告的方式回報(其承諾記憶體大小為 0),但 意味著,在主機系統處理記憶體時,很難歸因 供房客使用
memgraph -v
較少處理記憶體資訊,但會讓使用者
也就是自行處理,來判斷記憶體用量您也可以
難以判斷 VMO 是來自 sysmem
因為名稱必須一致
整合方法
任何想要完整且準確查看 sysmem VMO 的公用程式,都必須
合成檢查和 ZX_INFO_PROCESS_VMOS
資訊。Sysmem 檢查
資料應為存在 sysmem VMO 的可靠資料來源
是可靠資料來源,程序會保留對 VMO 的參照。這會導致
需要針對邏輯緩衝區集合項目進行疊代,然後列出
孩子,然後瀏覽 ZX_INFO_PROCESS_VMOS
找出其尺寸,
哪些程序提及其子項
公用程式可以為每個程序建立 ZX_INFO_HANDLE_TABLE
快照。接著
使用該資料表在 channel_koid
中查詢 Kid,以判斷
仍會保留 BufferCollection
在某些情況下,無法正確計算記憶體。 主要問題在於,系統不會回報管道訊息中保留的帳號代碼 因此無法將那些參照內容納入考量客戶 可將 VMO 帳號代碼推進管道,一律不讀取管道內容,且 連核心都不知道是誰把記憶體歸因於誰。偵錯 在這種情況下,用戶端資訊可做為備用項。
未來的潛在變更
為每個用戶端建立中間 VMO,讓 sysmem 可以判斷 用戶端仍能參照 VMO
讓元件架構將無法偽造的 ID 傳送至 sysmem 要求用戶端傳遞可偽造的偵錯名稱