Ion ABI 變化

搭載核心 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_SYNCION_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_sync_fd(ion_fd, buf_fd);

else

ioctl(buf_fd, DMA_BUF_IOCTL_SYNC, ...);

對於核心內客戶端,由於 Ion 不再導出任何面向核心的 API,因此先前透過ion_import_dma_buf_fd()使用核心內 Ion 核心 API 的驅動程式必須轉換為使用核心內 dma-buf APIdma_buf_get()

未來 Ion ABI 中斷

在將 Ion 從暫存樹中移出之前,未來的核心版本可能需要再次破壞 Ion ABI。 Android 系統團隊預計這些變更不會影響使用下一 Android 版本啟動的設備,但此類變更可能會影響使用後續 Android 版本啟動的裝置。

例如,上游社群建議將單一/dev/ion節點分割為多個按堆節點(例如/dev/ion/heap0 ),以使裝置能夠將不同的 SELinux 策略應用於每個堆疊。如果此變更在未來的核心版本中實現,它將破壞 Ion ABI。