搭載核心 4.14 及更高版本的裝置受到Ion 核心模組重大重構的影響,許多供應商圖形記憶體分配器 (gralloc) 硬體抽象層 (HAL) 實作呼叫該模組來分配共享記憶體緩衝區。本文提供了有關將舊供應商程式碼遷移到新版本 Ion 的指南,並討論了未來可能的應用程式二進位介面 (ABI) 中斷。
關於Ion
Ion 是上游內核的正在進行的暫存樹的一部分。在暫存過程中,Ion 的使用者空間到核心 ABI 可能會在主要核心版本之間中斷。雖然Ion ABI 中斷不會直接影響普通應用程式或已發布的設備,但遷移到新的主要核心版本的供應商可能會遇到影響呼叫 Ion 的供應商程式碼的變更。此外,當 Android 系統團隊與上游合作將 Ion 從暫存樹中移出時,未來可能會發生 ABI 中斷。
android-4.14 中的變化
Kernel 4.12 大量重構了 Ion 核心程式碼,清理並刪除了 Ion 與其他核心框架重疊的部分。因此,許多舊版 Ion ioctl 不再相關並已被刪除。
移除 Ion 用戶端和手柄
在核心 4.12 之前,開啟/dev/ion
會指派一個Ion 用戶端。 ION_IOC_ALLOC
ioctl 分配一個新的緩衝區並將其作為Ion 句柄返回到用戶空間(一個僅對分配它的 Ion 用戶端有意義的不透明整數)。為了將緩衝區對應到使用者空間或與其他程序共用它們,使用ION_IOC_SHARE
ioctl 將 Ion 句柄重新匯出為 dma-buf fd。
在核心4.12中, ION_IOC_ALLOC
ioctl直接輸出dma-buf fds。中間 Ion 句柄狀態以及所有消耗或產生 Ion 句柄的 ioctl 已被刪除。由於 dma-buf fd 不綁定到特定的 Ion 用戶端,因此不再需要ION_IOC_SHARE
ioctl,並且所有 Ion 用戶端基礎設施均已刪除。
新增快取一致性 ioctl
在核心 4.12 之前,Ion 提供了ION_IOC_SYNC
ioctl 來將檔案描述子與記憶體同步。這個 ioctl 的文檔很少且不靈活。因此,許多供應商實作了自訂 ioctl 來執行快取維護。
內核 4.12 將ION_IOC_SYNC
替換為linux/dma-buf.h中定義的DMA_BUF_IOCTL_SYNC ioctl
。在每次 CPU 存取開始和結束時呼叫DMA_BUF_IOCTL_SYNC
,並使用標誌指定這些存取是讀取和/或寫入。儘管DMA_BUF_IOCTL_SYNC
比ION_IOC_SYNC
更詳細,但它使用戶空間能夠更好地控制底層快取維護操作。
DMA_BUF_IOCTL_SYNC
是內核穩定 ABI 的一部分,可與所有 dma-buf fd 一起使用,無論它們是否由 Ion 分配。
將供應商代碼遷移到 android-4.12+
對於使用者空間客戶端,Android 系統團隊強烈鼓勵使用libion 而不是開放編碼的ioctl()
呼叫。從 Android 9 開始,libion 會在執行時間自動偵測 Ion ABI,並嘗試掩蓋核心之間的任何差異。但是,在內核 4.12 之後,任何產生或使用ion_user_handle_t
句柄的 libion 函數都不再運作。您可以將這些函數替換為 dma-buf fds 上的以下等效操作,這些操作適用於迄今為止的所有版本的核心。
舊版 ion_user_handle_t 呼叫 | 等效 dma-buf fd 調用 |
---|---|
ion_alloc(ion_fd, …, &buf_handle) | ion_alloc_fd(ion_fd, ..., &buf_fd) |
ion_share(ion_fd, buf_handle, &buf_fd) | N/A(DMA-buf fds 不需要此呼叫) |
ion_map(ion_fd, buf_handle, ...) | mmap(buf_fd, ...) |
ion_free(ion_fd, buf_handle) | close(buf_fd) |
ion_import(ion_fd, buf_fd, &buf_handle) | N/A(DMA-buf fds 不需要此呼叫) |
ion_sync_fd(ion_fd, buf_fd) | If (ion_is_legacy(ion_fd)) |
對於核心內客戶端,由於 Ion 不再導出任何面向核心的 API,因此先前透過ion_import_dma_buf_fd()
使用核心內 Ion 核心 API 的驅動程式必須轉換為使用核心內 dma-buf API和dma_buf_get()
。
未來 Ion ABI 中斷
在將 Ion 從暫存樹中移出之前,未來的核心版本可能需要再次破壞 Ion ABI。 Android 系統團隊預計這些變更不會影響使用下一 Android 版本啟動的設備,但此類變更可能會影響使用後續 Android 版本啟動的裝置。
例如,上游社群建議將單一/dev/ion
節點分割為多個按堆節點(例如/dev/ion/heap0
),以使裝置能夠將不同的 SELinux 策略應用於每個堆疊。如果此變更在未來的核心版本中實現,它將破壞 Ion ABI。