تغییرات یون ABI

دستگاه‌هایی که هسته 4.14 و بالاتر را ارسال می‌کنند، تحت‌تأثیر بازسازی عمده ماژول هسته یون قرار می‌گیرند، که بسیاری از پیاده‌سازی‌های لایه انتزاعی سخت‌افزار (HAL) تخصیص‌دهنده حافظه گرافیکی فروشنده (gralloc) برای تخصیص بافرهای حافظه مشترک فراخوانی می‌کنند. این مقاله راهنمایی در مورد انتقال کد فروشنده قدیمی به نسخه جدید Ion ارائه می‌کند و در مورد خرابی‌های احتمالی رابط باینری برنامه (ABI) در آینده بحث می‌کند.

درباره یون

یون بخشی از درخت مرحله‌بندی هسته بالادست است. در حین مرحله‌بندی، ABI فضای کاربر به هسته Ion ممکن است بین نسخه‌های اصلی هسته شکسته شود. در حالی که شکست های Ion ABI مستقیماً بر برنامه های معمولی یا دستگاه هایی که قبلاً راه اندازی شده اند تأثیر نمی گذارد ، فروشندگانی که به نسخه های جدید هسته اصلی مهاجرت می کنند ممکن است با تغییراتی مواجه شوند که بر فراخوانی کد فروشنده به Ion تأثیر می گذارد. علاوه بر این، زمانی که تیم سیستم‌های Android با upstream کار می‌کنند تا Ion را از درخت مرحله‌بندی خارج کنند، ممکن است خرابی‌های ABI در آینده رخ دهد.

تغییرات اندروید 4.14

Kernel 4.12 به شدت کد هسته Ion را بازسازی کرد و بخش‌هایی از Ion را که با سایر چارچوب‌های هسته همپوشانی داشتند، پاکسازی و حذف کرد. در نتیجه، بسیاری از Ion ioctl های قدیمی دیگر مرتبط نیستند و حذف شده اند.

حذف کلاینت ها و دسته های یون

قبل از کرنل 4.12، باز کردن /dev/ion یک کلاینت Ion را اختصاص داد. ION_IOC_ALLOC ioctl یک بافر جدید اختصاص داد و آن را به عنوان یک دسته Ion به فضای کاربر برگرداند (یک عدد صحیح مات که فقط برای مشتری Ion که آن را اختصاص داده معنی دارد). برای نگاشت بافرها در فضای کاربر یا به اشتراک گذاشتن آنها با سایر فرآیندها، دسته های یون به صورت fds dma-buf با استفاده از ION_IOC_SHARE ioctl دوباره صادر شدند.

در هسته 4.12، ION_IOC_ALLOC ioctl مستقیماً dma-buf fds را خروجی می‌دهد. حالت میانی دسته یون به همراه تمام ioctlهایی که دسته های یونی را مصرف می کنند یا تولید می کنند حذف شده است. از آنجایی که fds dma-buf به مشتری های Ion خاص متصل نیست، ioctl ION_IOC_SHARE دیگر مورد نیاز نیست و تمام زیرساخت های مشتری Ion حذف شده است.

افزودن ioctlهای کش-همسویی

قبل از کرنل 4.12، Ion یک ioctl ION_IOC_SYNC برای همگام سازی توصیفگر فایل با حافظه ارائه می کرد. این ioctl مستند ضعیف و غیر قابل انعطاف بود. در نتیجه، بسیاری از فروشندگان ioctls سفارشی را برای انجام نگهداری حافظه پنهان پیاده سازی کردند.

هسته 4.12 جایگزین ION_IOC_SYNC با DMA_BUF_IOCTL_SYNC ioctl تعریف شده در linux/dma-buf.h شد. DMA_BUF_IOCTL_SYNC در ابتدا و انتهای هر دسترسی به CPU، با پرچم‌هایی که مشخص می‌کنند این دسترسی‌ها خواندن و/یا نوشتن هستند تماس بگیرید. اگرچه DMA_BUF_IOCTL_SYNC پرمخاطب تر از ION_IOC_SYNC است، اما به فضای کاربران کنترل بیشتری بر عملیات نگهداری حافظه پنهان می دهد.

DMA_BUF_IOCTL_SYNC بخشی از ABI پایدار هسته است و با همه fds های dma-buf قابل استفاده است، خواه توسط Ion تخصیص داده شده باشند یا نه.

انتقال کد فروشنده به android-4.12+

برای مشتریان فضای کاربری ، تیم سیستم‌های اندروید قویاً استفاده از فراخوان‌های ioctl() libion ​​را به جای کدگذاری باز تشویق می‌کنند. از اندروید 9، libion ​​به طور خودکار Ion ABI را در زمان اجرا شناسایی می کند و سعی می کند هر گونه تفاوت بین هسته ها را پنهان کند. با این حال، هر توابع libion ​​که دسته‌های ion_user_handle_t تولید یا مصرف می‌کند، بعد از کرنل 4.12 دیگر کار نمی‌کند. می‌توانید این توابع را با عملیات‌های معادل زیر در 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 (این تماس با fds dma-buf مورد نیاز نیست)
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 (این تماس با fds dma-buf مورد نیاز نیست)
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 رو به هسته صادر نمی‌کند، درایورهایی که قبلاً از API هسته Ion درون هسته با ion_import_dma_buf_fd() استفاده می‌کردند باید برای استفاده از API dma-buf درون هسته با dma_buf_get() تبدیل شوند.

آینده یون ABI می شکند

قبل از اینکه Ion بتواند از درخت مرحله‌بندی خارج شود، ممکن است در نسخه‌های هسته آینده نیاز به شکستن Ion ABI دوباره باشد. تیم سیستم‌های اندروید انتظار ندارند این تغییرات روی دستگاه‌هایی که با نسخه اندروید بعدی راه‌اندازی می‌شوند تأثیر بگذارد، اما چنین تغییراتی ممکن است دستگاه‌هایی را که با نسخه‌های اندروید بعدی راه‌اندازی می‌شوند تحت تأثیر قرار دهد.

به عنوان مثال، جامعه بالادستی پیشنهاد کرده است که گره /dev/ion منفرد را به چندین گره در هر هیپ (به عنوان مثال، /dev/ion/heap0 ) تقسیم کند تا دستگاه‌ها بتوانند سیاست‌های SELinux مختلف را برای هر پشته اعمال کنند. اگر این تغییر در نسخه بعدی هسته اجرا شود، Ion ABI را می شکند.