許多 Android OEM 出於各種原因修改 ION 內核驅動程序,例如添加供應商堆和自定義緩存管理(有關這些修改的詳細信息,請參閱集成 ION 內存分配器)。為了使 OEM 在使用通用內核映像 (GKI)時能夠保留此類修改,Android Common Kernel v5.4 引入了一個框架,用於模塊化供應商特定的 ION 堆,同時保持內置的核心 ION 驅動程序。下圖顯示了內核映像佈局.
圖 1.模塊化 ION 內核驅動程序
模塊化 ION 堆具有以下優點。
- ION 核心驅動程序可以成為 GKI 映像的一部分,使所有與設備無關的性能優化和錯誤修復能夠覆蓋所有設備。
- 公共內核中的 ION 核心驅動程序可以處理堆註冊並管理與用戶空間和內核客戶端的接口。僅需要供應商堆模塊來實現自定義堆操作。
- ION 核心驅動程序(作為 GKI 的一部分)可以包含掛鉤,以便更輕鬆地跟踪內存使用情況,這在每個 OEM 擁有自己的 ION 驅動程序版本時是不可能的。
- 模塊化供應商 ION 堆應該使將來向
dmabuf
堆的任何轉換變得更容易。
實施
ION 堆模塊可以註冊自己的dmabuf
操作來覆蓋核心 ION 驅動程序註冊的操作。如果堆實現缺少必要的覆蓋,核心 ION 驅動程序不支持的dmabuf
操作(例如get_flags()
)返回-EOPNOTSUPP
。
為了提高性能, dmabuf
驅動程序可以執行部分緩存維護(請參閱更改列表)。內核客戶端可以使用dma_buf_begin_cpu_access_partial
和dma_buf_end_cpu_access_partial
函數來執行部分緩存維護。
Android Common Kernel 包含系統的模塊化實現和連續內存分配器 (CMA) 堆,用作堆模塊化的參考。
ION UAPI 標頭的更改
ION 用戶空間 API (UAPI) 標頭包含一個ion_heap_id
枚舉,用於定義供供應商堆使用的堆 ID 範圍。
/**
* ion_heap_id - list of heap IDs that Android can use
*
* @ION_HEAP_SYSTEM ID for the ION_HEAP_TYPE_SYSTEM
* @ION_HEAP_DMA_START Start of reserved ID range for heaps of type ION_HEAP_TYPE_DMA
* @ION_HEAP_DMA_END End of reserved ID range for heaps of type ION_HEAP_TYPE_DMA
* @ION_HEAP_CUSTOM_START Start of reserved ID range for heaps of custom type
* @ION_HEAP_CUSTOM_END End of reserved ID range for heaps of custom type
*/
enum ion_heap_id {
ION_HEAP_SYSTEM = (1 << ION_HEAP_TYPE_SYSTEM),
ION_HEAP_DMA_START = (ION_HEAP_SYSTEM << 1),
ION_HEAP_DMA_END = (ION_HEAP_DMA_START << 7),
ION_HEAP_CUSTOM_START = (ION_HEAP_DMA_END << 1),
ION_HEAP_CUSTOM_END = (ION_HEAP_CUSTOM_START << 22),
};
此外,新的IOCTL
( ION_IOC_ABI_VERSION
) 可以幫助用戶空間客戶端確定是否正在使用模塊化堆。
覆蓋通用系統堆
ION 系統堆是內置的並且是 GKI 映像的一部分,以確保需要訪問通用/設備獨立堆的任何功能都可以依賴於它的存在。因此,您不能覆蓋ION_HEAP_SYSTEM
的堆 ID。要創建自定義系統堆,請使用自定義範圍( ION_HEAP_CUSTOM_START
到ION_HEAP_CUSTOM_END
)中的堆 ID 來執行分配。