Thay đổi ABI của ion

Các thiết bị vận chuyển kernel 4.14 trở lên bị ảnh hưởng bởi quá trình tái cấu trúc chính của mô-đun hạt nhân Ion , mà nhiều quá trình triển khai lớp trừu tượng phần cứng bộ cấp phát bộ nhớ đồ họa (gralloc) (HAL) của nhà cung cấp gọi để phân bổ bộ nhớ đệm dùng chung. Bài viết này cung cấp hướng dẫn về cách di chuyển mã của nhà cung cấp cũ sang phiên bản mới của Ion và thảo luận về các lỗi có thể xảy ra trong giao diện nhị phân ứng dụng (ABI) trong tương lai.

Về ion

Ion là một phần của cây phân giai đoạn đang thực hiện công việc của hạt nhân ngược dòng. Trong khi đang chạy thử, ABI từ không gian người dùng đến hạt nhân của Ion có thể bị hỏng giữa các phiên bản hạt nhân chính. Mặc dù việc ngắt Ion ABI không ảnh hưởng trực tiếp đến các ứng dụng thông thường hoặc các thiết bị đã ra mắt , nhưng các nhà cung cấp đang chuyển sang các phiên bản hạt nhân chính mới có thể gặp phải những thay đổi ảnh hưởng đến việc gọi mã nhà cung cấp vào Ion. Ngoài ra, sự cố ABI trong tương lai có thể xảy ra khi nhóm hệ thống Android làm việc ngược dòng để di chuyển Ion ra khỏi cây phân giai đoạn.

Những thay đổi trong android-4.14

Kernel 4.12 đã tái cấu trúc rất nhiều mã hạt nhân Ion, dọn dẹp và loại bỏ các phần của Ion trùng lặp với các khung hạt nhân khác. Kết quả là nhiều Ion ioctls cũ không còn phù hợp và đã bị xóa.

Loại bỏ các máy khách và tay cầm Ion

Trước kernel 4.12, việc mở /dev/ion đã cấp phát Ion client . ION_IOC_ALLOC ioctl đã phân bổ một bộ đệm mới và trả nó về không gian người dùng dưới dạng bộ điều khiển Ion (một số nguyên mờ chỉ có ý nghĩa đối với ứng dụng khách Ion đã phân bổ nó). Để ánh xạ bộ đệm vào không gian người dùng hoặc chia sẻ chúng với các quy trình khác, bộ điều khiển Ion đã được xuất lại dưới dạng dma-buf fds bằng cách sử dụng ION_IOC_SHARE ioctl.

Trong kernel 4.12, ION_IOC_ALLOC ioctl trực tiếp xuất ra dma-buf fds. Trạng thái xử lý Ion trung gian đã bị loại bỏ, cùng với tất cả các ioctls tiêu thụ hoặc tạo ra các xử lý Ion. Vì dma-buf fds không bị ràng buộc với các máy khách Ion cụ thể nên ION_IOC_SHARE ioctl không còn cần thiết nữa và tất cả cơ sở hạ tầng máy khách Ion đã bị xóa.

Bổ sung ioctls kết hợp bộ đệm

Trước kernel 4.12, Ion đã cung cấp ION_IOC_SYNC ioctl để đồng bộ hóa bộ mô tả tệp với bộ nhớ. Ioctl này được ghi chép kém và không linh hoạt. Do đó, nhiều nhà cung cấp đã triển khai ioctls tùy chỉnh để thực hiện bảo trì bộ đệm.

Kernel 4.12 đã thay thế ION_IOC_SYNC bằng DMA_BUF_IOCTL_SYNC ioctl được xác định trong linux/dma-buf.h . Gọi DMA_BUF_IOCTL_SYNC khi bắt đầu và kết thúc mỗi lần truy cập CPU, kèm theo các cờ chỉ định xem những truy cập này là đọc và/hoặc ghi. Mặc dù DMA_BUF_IOCTL_SYNC dài dòng hơn ION_IOC_SYNC nhưng nó mang lại cho không gian người dùng nhiều quyền kiểm soát hơn đối với các hoạt động bảo trì bộ nhớ đệm cơ bản.

DMA_BUF_IOCTL_SYNC là một phần của ABI ổn định của hạt nhân và có thể sử dụng được với tất cả các fds dma-buf, cho dù chúng có được Ion phân bổ hay không.

Di chuyển mã nhà cung cấp sang android-4.12+

Đối với các ứng dụng khách trong không gian người dùng , nhóm hệ thống Android đặc biệt khuyến khích sử dụng các lệnh gọi libion ​​thay vì các lệnh gọi ioctl() mã hóa mở. Kể từ Android 9, libion ​​tự động phát hiện Ion ABI trong thời gian chạy và cố gắng che giấu mọi khác biệt giữa các hạt nhân. Tuy nhiên, bất kỳ hàm libion ​​nào tạo ra hoặc tiêu thụ các bộ điều khiển ion_user_handle_t đều không còn hoạt động sau kernel 4.12. Bạn có thể thay thế các hàm này bằng các thao tác tương đương sau đây trên dma-buf fds, hoạt động trên tất cả các phiên bản kernel cho đến nay.

Cuộc gọi ion_user_handle_t kế thừa Cuộc gọi fd dma-buf tương đương
ion_alloc(ion_fd, …, &buf_handle) ion_alloc_fd(ion_fd, ..., &buf_fd)
ion_share(ion_fd, buf_handle, &buf_fd) Không áp dụng (lệnh gọi này không cần thiết với 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) Không áp dụng (lệnh gọi này không cần thiết với 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, ...);

Đối với các máy khách trong nhân , do Ion không còn xuất bất kỳ API nào đối với nhân, nên các trình điều khiển trước đây đã sử dụng API nhân Ion trong nhân với ion_import_dma_buf_fd() phải được chuyển đổi để sử dụng API dma-buf trong nhân với dma_buf_get() .

Sự phá vỡ Ion ABI trong tương lai

Trước khi Ion có thể được di chuyển ra khỏi cây phân tầng, các bản phát hành kernel trong tương lai có thể cần phải phá vỡ Ion ABI một lần nữa. Nhóm hệ thống Android dự kiến ​​những thay đổi này sẽ không ảnh hưởng đến các thiết bị khởi chạy với phiên bản Android tiếp theo, nhưng những thay đổi đó có thể ảnh hưởng đến các thiết bị khởi chạy với phiên bản Android tiếp theo.

Ví dụ: cộng đồng thượng nguồn đã đề xuất chia nút /dev/ion đơn thành nhiều nút trên mỗi heap (ví dụ: /dev/ion/heap0 ) để cho phép các thiết bị áp dụng các chính sách SELinux khác nhau cho mỗi heap. Nếu thay đổi này được triển khai trong bản phát hành kernel trong tương lai, nó sẽ phá vỡ Ion ABI.